@@ -130,6 +130,10 @@ class UMAWrapper(nn.Module, BaseModelMixin):
130130 UMA task: one of ``_UMA_TASKS``. Determines which per-task head
131131 in the multi-task model is used and which inputs (charge, spin)
132132 must be populated.
133+ train : bool
134+ ``False`` (default) freezes all weights for inference (lossless for
135+ autograd forces); ``True`` keeps fairchem's trainable/frozen split
136+ so weights stay exposed for fine-tuning.
133137
134138 Attributes
135139 ----------
@@ -139,7 +143,9 @@ class UMAWrapper(nn.Module, BaseModelMixin):
139143 The UMA task this wrapper is pinned to.
140144 """
141145
142- def __init__ (self , predict_unit : Any , task_name : str = "omol" ) -> None :
146+ def __init__ (
147+ self , predict_unit : Any , task_name : str = "omol" , train : bool = False
148+ ) -> None :
143149 super ().__init__ ()
144150 if task_name not in _UMA_TASKS :
145151 raise ValueError (
@@ -198,6 +204,16 @@ def __init__(self, predict_unit: Any, task_name: str = "omol") -> None:
198204 active_outputs = active_outputs ,
199205 )
200206
207+ # Inference (train=False): freeze all weights — conservative forces
208+ # come from autograd w.r.t. positions, so this is lossless and avoids
209+ # building a weight-grad graph each forward. Training: leave fairchem's
210+ # loaded trainable/frozen split intact so weights stay exposed.
211+ self ._train = train
212+ if not train :
213+ for p in self .predict_unit .model .parameters ():
214+ p .requires_grad_ (False )
215+ self .train (train )
216+
201217 # ------------------------------------------------------------------
202218 # Construction
203219 # ------------------------------------------------------------------
@@ -210,6 +226,7 @@ def from_checkpoint(
210226 device : str | torch .device = "cpu" ,
211227 inference_settings : Any = "default" ,
212228 overrides : dict | None = None ,
229+ train : bool = False ,
213230 ) -> "UMAWrapper" :
214231 """Resolve and load a UMA checkpoint.
215232
@@ -242,6 +259,14 @@ def from_checkpoint(
242259 overrides : dict | None
243260 Optional overrides forwarded to fairchem's inference-settings
244261 builder.
262+ train : bool
263+ If ``False`` (default), freeze all weights for inference —
264+ lossless, since conservative forces come from autograd on
265+ positions. If ``True``, keep fairchem's loaded trainable/frozen
266+ split so weights remain exposed for fine-tuning. Note: the
267+ ``forward`` path goes through fairchem's inference ``predict``
268+ (eval mode, detached forces); gradient-based training requires a
269+ separate path through the raw model.
245270 """
246271 import os as _os
247272
@@ -272,7 +297,7 @@ def from_checkpoint(
272297 f"local file path. Known names: "
273298 f"{ sorted (pretrained_mlip .available_models )[:6 ]} ..."
274299 )
275- return cls (predict_unit , task_name = task_name )
300+ return cls (predict_unit , task_name = task_name , train = train )
276301
277302 def _extract_cutoff (self ) -> float :
278303 """Pull the radial cutoff from the loaded backbone.
0 commit comments