88#
99# Systems are ``dpdata.System`` objects; cache keys are computed from
1010# data fingerprints and resolved checkpoint metadata.
11+ #
12+ # Note: ``load_or_extract()`` and ``ensure_per_system_cache()`` live in
13+ # ``dpa_adapt.finetuner`` to avoid an import cycle (those functions need
14+ # ``DPAFineTuner``, while ``finetuner`` imports cache helpers from here).
1115
1216from __future__ import (
1317 annotations ,
@@ -125,78 +129,7 @@ def _cache_key(
125129
126130
127131# ---------------------------------------------------------------------------
128- # bulk cache
129- # ---------------------------------------------------------------------------
130-
131-
132- def load_or_extract (
133- systems : list ,
134- pretrained : str ,
135- model_branch : str | None = None ,
136- pooling : str = "mean" ,
137- cache : bool = True ,
138- type_map : list [str ] | tuple [str , ...] | None = None ,
139- ) -> np .ndarray :
140- """Return descriptors for *systems*, using the cache when possible.
141-
142- Parameters
143- ----------
144- systems : list[dpdata.System]
145- Systems to extract descriptors from.
146- pretrained : str
147- Path to the DPA checkpoint.
148- model_branch : str, optional
149- Branch name.
150- pooling : str
151- Pooling strategy.
152- cache : bool
153- If False the cache is bypassed entirely.
154- type_map : list[str] or tuple[str, ...], optional
155- Element symbols used to build the descriptor model and cache key.
156-
157- Returns
158- -------
159- np.ndarray, shape ``(n_frames_total, feat_dim)``
160- """
161- if cache :
162- key = _cache_key (
163- systems ,
164- pretrained ,
165- model_branch ,
166- pooling ,
167- type_map = type_map ,
168- )
169- cache_path = _cache_dir () / f"{ key } .npy"
170- if cache_path .is_file ():
171- _LOG .info ("Descriptor cache hit: %s" , cache_path .name )
172- return np .load (cache_path )
173- _LOG .info ("Descriptor cache miss; extracting..." )
174- else :
175- _LOG .info ("Descriptor cache bypassed (cache=False)." )
176-
177- from dpa_adapt .finetuner import (
178- DPAFineTuner ,
179- )
180-
181- extractor = DPAFineTuner (
182- pretrained = pretrained ,
183- model_branch = model_branch ,
184- predictor = "linear" ,
185- pooling = pooling ,
186- type_map = list (type_map ) if type_map else None ,
187- )
188- descriptors = extractor ._extract_features (systems )
189-
190- if cache :
191- cache_path .parent .mkdir (parents = True , exist_ok = True )
192- np .save (cache_path , descriptors )
193- _LOG .info ("Cached descriptors to %s" , cache_path )
194-
195- return descriptors
196-
197-
198- # ---------------------------------------------------------------------------
199- # per-system cache — used by cross_validate to avoid OOM
132+ # per-system cache path helpers
200133# ---------------------------------------------------------------------------
201134
202135
@@ -216,74 +149,6 @@ def _per_system_cache_path(
216149 return _cache_dir () / "per_system" / f"{ fp } .npy"
217150
218151
219- def ensure_per_system_cache (
220- systems : list ,
221- pretrained : str ,
222- model_branch : str | None = None ,
223- pooling : str = "mean" ,
224- type_map : list [str ] | tuple [str , ...] | None = None ,
225- ) -> None :
226- """Ensure every system has its descriptors cached to disk.
227-
228- Existing cache files are reused as-is. Missing ones are extracted one
229- system at a time for low peak memory.
230- """
231- missing : list = []
232- for system in systems :
233- if not _per_system_cache_path (
234- system ,
235- pretrained ,
236- model_branch ,
237- pooling ,
238- type_map ,
239- ).is_file ():
240- missing .append (system )
241-
242- if not missing :
243- _LOG .info (
244- "All %d systems have per-system cache; nothing to extract." , len (systems )
245- )
246- return
247-
248- import torch
249-
250- from dpa_adapt .finetuner import (
251- DPAFineTuner ,
252- )
253-
254- _LOG .info (
255- "%d/%d systems missing per-system cache; extracting one by one..." ,
256- len (missing ),
257- len (systems ),
258- )
259-
260- extractor = DPAFineTuner (
261- pretrained = pretrained ,
262- model_branch = model_branch ,
263- predictor = "linear" ,
264- pooling = pooling ,
265- type_map = list (type_map ) if type_map else None ,
266- )
267-
268- for i , system in enumerate (missing ):
269- cache_path = _per_system_cache_path (
270- system ,
271- pretrained ,
272- model_branch ,
273- pooling ,
274- type_map ,
275- )
276- cache_path .parent .mkdir (parents = True , exist_ok = True )
277- desc = extractor ._extract_features ([system ])
278- np .save (cache_path , desc )
279- if extractor ._device is not None and extractor ._device .type == "cuda" :
280- torch .cuda .empty_cache ()
281- if i > 0 and i % 50 == 0 :
282- _LOG .info (" per-system cache: %d/%d done" , i , len (missing ))
283-
284- _LOG .info ("Per-system cache ready (%d systems)." , len (systems ))
285-
286-
287152def get_per_system_descriptor (
288153 system : dpdata .System ,
289154 pretrained : str ,
0 commit comments