Feature Extraction
Transformers
Safetensors
cue
user-simulation
dialogue
persona
custom_code
AnjaliRuban commited on
Commit
100bc30
·
verified ·
1 Parent(s): d38f8f8

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. checkpoint.py +7 -18
  2. configuration_cue.py +5 -2
  3. modeling_cue.py +9 -3
  4. sampler_sample.py +45 -0
checkpoint.py CHANGED
@@ -13,14 +13,8 @@ from .configuration_cue import CueConfig
13
  JOINT_CONFIG_NAME = "unified_config.json"
14
  JOINT_WEIGHTS_NAME = "model.pt"
15
  REFINED_DECODER_STATE = "decoder_state.pt"
16
- # Newest first; `stage2_config.json` predates the pipeline rename.
17
- REFINED_CONFIG_NAMES = (
18
- "refinement_config.json",
19
- "decoder_refinement_config.json",
20
- "stage2_config.json",
21
- )
22
- # Newest first; `stage1_checkpoint` predates the rename.
23
- JOINT_CHECKPOINT_KEYS = ("joint_training_checkpoint", "stage1_checkpoint")
24
 
25
  LAYOUT_NATIVE = "native"
26
  LAYOUT_JOINT = "joint"
@@ -55,16 +49,13 @@ def detect_layout(directory: str | Path) -> str:
55
  return LAYOUT_NATIVE
56
  raise ValueError(
57
  f"{directory} is not a cue-hf, joint training, or refinement checkpoint "
58
- f"(looked for config.json, {JOINT_CONFIG_NAME}, {'/'.join(REFINED_CONFIG_NAMES)})"
59
  )
60
 
61
 
62
  def _refined_config_path(directory: Path) -> Path | None:
63
- for name in REFINED_CONFIG_NAMES:
64
- path = directory / name
65
- if path.is_file():
66
- return path
67
- return None
68
 
69
 
70
  def config_from_joint_dir(directory: str | Path) -> CueConfig:
@@ -91,12 +82,10 @@ def resolve_refined(directory: str | Path) -> tuple[Path, Path]:
91
  if config_path is None:
92
  raise ValueError(f"{directory} has no refinement config")
93
  payload = json.loads(config_path.read_text(encoding="utf-8"))
94
- joint = next(
95
- (payload[key] for key in JOINT_CHECKPOINT_KEYS if payload.get(key)), None
96
- )
97
  if not joint:
98
  raise ValueError(
99
- f"{config_path} has none of {JOINT_CHECKPOINT_KEYS}; cannot find the "
100
  "joint training checkpoint holding the encoder"
101
  )
102
  decoder_state = directory / REFINED_DECODER_STATE
 
13
  JOINT_CONFIG_NAME = "unified_config.json"
14
  JOINT_WEIGHTS_NAME = "model.pt"
15
  REFINED_DECODER_STATE = "decoder_state.pt"
16
+ REFINED_CONFIG_NAME = "refinement_config.json"
17
+ JOINT_CHECKPOINT_KEY = "joint_training_checkpoint"
 
 
 
 
 
 
18
 
19
  LAYOUT_NATIVE = "native"
20
  LAYOUT_JOINT = "joint"
 
49
  return LAYOUT_NATIVE
50
  raise ValueError(
51
  f"{directory} is not a cue-hf, joint training, or refinement checkpoint "
52
+ f"(looked for config.json, {JOINT_CONFIG_NAME}, {REFINED_CONFIG_NAME})"
53
  )
54
 
55
 
56
  def _refined_config_path(directory: Path) -> Path | None:
57
+ path = directory / REFINED_CONFIG_NAME
58
+ return path if path.is_file() else None
 
 
 
59
 
60
 
61
  def config_from_joint_dir(directory: str | Path) -> CueConfig:
 
82
  if config_path is None:
83
  raise ValueError(f"{directory} has no refinement config")
84
  payload = json.loads(config_path.read_text(encoding="utf-8"))
85
+ joint = payload.get(JOINT_CHECKPOINT_KEY)
 
 
86
  if not joint:
87
  raise ValueError(
88
+ f"{config_path} has no {JOINT_CHECKPOINT_KEY}; cannot find the "
89
  "joint training checkpoint holding the encoder"
90
  )
91
  decoder_state = directory / REFINED_DECODER_STATE
configuration_cue.py CHANGED
@@ -12,6 +12,7 @@ from .encoder_model import (
12
  DEFAULT_PASSAGE_PREFIX,
13
  DEFAULT_QUERY_PREFIX,
14
  )
 
15
 
16
  # Defaults mirror the final CUE joint-training config (ModernBERT turn encoder).
17
  DEFAULT_ENCODER_CONFIG: dict[str, Any] = {
@@ -59,7 +60,7 @@ class CueConfig(PretrainedConfig):
59
  style_command_slots: int = 4,
60
  slot_embedding_dim: int = 64,
61
  target_max_tokens: int = 2048,
62
- session_preprocess: str = "full",
63
  decode_temperature: float = 0.0,
64
  decode_max_new_tokens: int = 2048,
65
  slot_dedup_jaccard: float = 0.8,
@@ -81,7 +82,9 @@ class CueConfig(PretrainedConfig):
81
  self.style_command_slots = int(style_command_slots)
82
  self.slot_embedding_dim = int(slot_embedding_dim)
83
  self.target_max_tokens = int(target_max_tokens)
84
- self.session_preprocess = str(session_preprocess)
 
 
85
  self.decode_temperature = float(decode_temperature)
86
  self.decode_max_new_tokens = int(decode_max_new_tokens)
87
  self.slot_dedup_jaccard = float(slot_dedup_jaccard)
 
12
  DEFAULT_PASSAGE_PREFIX,
13
  DEFAULT_QUERY_PREFIX,
14
  )
15
+ from .session_preprocess import normalize_session_preprocess
16
 
17
  # Defaults mirror the final CUE joint-training config (ModernBERT turn encoder).
18
  DEFAULT_ENCODER_CONFIG: dict[str, Any] = {
 
60
  style_command_slots: int = 4,
61
  slot_embedding_dim: int = 64,
62
  target_max_tokens: int = 2048,
63
+ session_preprocess: str | None = "full",
64
  decode_temperature: float = 0.0,
65
  decode_max_new_tokens: int = 2048,
66
  slot_dedup_jaccard: float = 0.8,
 
82
  self.style_command_slots = int(style_command_slots)
83
  self.slot_embedding_dim = int(slot_embedding_dim)
84
  self.target_max_tokens = int(target_max_tokens)
85
+ # A config exported without an explicit mode carries null, and str(None) would reach
86
+ # the encoder as the literal "None".
87
+ self.session_preprocess = normalize_session_preprocess(session_preprocess)
88
  self.decode_temperature = float(decode_temperature)
89
  self.decode_max_new_tokens = int(decode_max_new_tokens)
90
  self.slot_dedup_jaccard = float(slot_dedup_jaccard)
modeling_cue.py CHANGED
@@ -23,7 +23,7 @@ from .decoder_model import CueDecoder
23
  from .encoder_model import CueEncoder
24
  from .example_pool import META_NAME, POOL_DIRNAME, ExamplePool, inject_examples
25
  from .log import log, warn
26
- from .sampler_sample import CueSampler, load_sampler
27
  from .schema import (
28
  COMMAND_BLOCK_SENTINEL,
29
  COMMAND_SLOT_SENTINEL,
@@ -156,8 +156,14 @@ class CueModel(PreTrainedModel):
156
  def attach_sampler(self, checkpoint: str | Path, **kwargs: Any) -> CueSampler:
157
  """Load a diffusion prior (``sampler.pt``) from a directory or Hub repo."""
158
 
159
- directory = resolve_local_dir(checkpoint, **kwargs)
160
- self._sampler = load_sampler(directory, device=str(self.device))
 
 
 
 
 
 
161
  return self._sampler
162
 
163
  def attach_example_pool(self, source: str | Path, *, split: str = "train") -> ExamplePool:
 
23
  from .encoder_model import CueEncoder
24
  from .example_pool import META_NAME, POOL_DIRNAME, ExamplePool, inject_examples
25
  from .log import log, warn
26
+ from .sampler_sample import SAMPLER_NAME, CueSampler, load_sampler
27
  from .schema import (
28
  COMMAND_BLOCK_SENTINEL,
29
  COMMAND_SLOT_SENTINEL,
 
156
  def attach_sampler(self, checkpoint: str | Path, **kwargs: Any) -> CueSampler:
157
  """Load a diffusion prior (``sampler.pt``) from a directory or Hub repo."""
158
 
159
+ source = Path(checkpoint)
160
+ if not source.is_dir():
161
+ from huggingface_hub import hf_hub_download
162
+
163
+ # Refined repos point sampler_id at the joint repo, so snapshotting it would
164
+ # pull that model's weights too: fetch the one file instead.
165
+ source = Path(hf_hub_download(str(checkpoint), SAMPLER_NAME, **kwargs))
166
+ self._sampler = load_sampler(source, device=str(self.device))
167
  return self._sampler
168
 
169
  def attach_example_pool(self, source: str | Path, *, split: str = "train") -> ExamplePool:
sampler_sample.py CHANGED
@@ -229,6 +229,51 @@ def load_sampler(
229
  )
230
 
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  def as_condition_tensor(
233
  condition: np.ndarray | torch.Tensor | list,
234
  *,
 
229
  )
230
 
231
 
232
+ """Keys ``load_sampler`` reads, plus provenance scalars. Everything else is training state."""
233
+ INFERENCE_KEYS = (
234
+ "schedule",
235
+ "mu",
236
+ "sigma",
237
+ "layernorm_weight",
238
+ "layernorm_bias",
239
+ "dim",
240
+ "config",
241
+ "checkpoint_hash",
242
+ "step",
243
+ )
244
+
245
+
246
+ def slim_sampler_payload(payload: dict[str, Any]) -> dict[str, Any]:
247
+ """Drop optimizer/scheduler/scaler state and the duplicate weight copy.
248
+
249
+ Training checkpoints hold ``model``, an EMA shadow, and optimizer moments. Inference
250
+ uses the EMA weights, so those are promoted into ``model`` and the rest is dropped:
251
+ one copy that loads identically whether or not ``use_ema`` is set.
252
+ """
253
+
254
+ ema = payload.get("ema")
255
+ if isinstance(ema, dict) and "shadow" in ema:
256
+ weights = ema["shadow"]
257
+ elif "model" in payload:
258
+ weights = payload["model"]
259
+ else:
260
+ raise KeyError("sampler payload has neither ema['shadow'] nor model weights")
261
+ slim: dict[str, Any] = {"model": weights}
262
+ slim.update({key: payload[key] for key in INFERENCE_KEYS if key in payload})
263
+ return slim
264
+
265
+
266
+ def slim_sampler_file(source: str | Path, destination: str | Path) -> Path:
267
+ """Rewrite a ``sampler.pt`` with only the tensors inference needs."""
268
+
269
+ source, destination = Path(source), Path(destination)
270
+ if source.is_dir():
271
+ source = source / SAMPLER_NAME
272
+ payload = torch.load(source, map_location="cpu", mmap=True, weights_only=False)
273
+ torch.save(slim_sampler_payload(payload), destination)
274
+ return destination
275
+
276
+
277
  def as_condition_tensor(
278
  condition: np.ndarray | torch.Tensor | list,
279
  *,