| name | primitive-hf-bridge |
| description | Bidirectional weight conversion between HuggingFace transformers format and curryTrain internal format, including offline fallback when the HF Hub is unreachable. Activate when the user asks "load HF weights", "HuggingFace bridge", "convert weights", "HF Hub unreachable", or "offline weight loading". |
Primitive · HFBridge
Bidirectional translation between HuggingFace transformers weight format and the model's internal layout, plus an offline path for when huggingface.co is unreachable.
What it does
- Import: take an HF model (or a local snapshot) and produce a state_dict matching the curryTrain model's layout.
- Export: take a curryTrain model and produce an HF-compatible directory (
config.json, model.safetensors, tokenizer files).
- Offline fallback: when network is unavailable, guide the user through manual download.
Interface (V1 stub)
from curry_train.primitives import HFBridge
bridge = HFBridge(curry_model_class=MyModel, hf_arch="LlamaForCausalLM")
state_dict = bridge.import_from_hf("Qwen/Qwen2.5-1.5B")
state_dict = bridge.import_from_hf("/path/to/local/Qwen2.5-1.5B")
bridge.export_to_hf(model, output_dir="./my-model", tokenizer=tokenizer)
Offline procedure
When the HF Hub call fails (network, firewall, or service outage), HFBridge should fall back to a clear guided procedure:
-
Detect the failure and categorize: NetworkError, AuthError, ModelNotFound.
-
Print a numbered set of recovery steps:
HF Hub unreachable. To proceed offline:
1. From a machine with internet, download the model:
huggingface-cli download Qwen/Qwen2.5-1.5B \
--local-dir ./Qwen2.5-1.5B \
--local-dir-use-symlinks False
2. Copy ./Qwen2.5-1.5B to this machine.
3. Re-run with the local path:
bridge.import_from_hf("/abs/path/to/Qwen2.5-1.5B")
For details on minimum files needed (config.json, *.safetensors,
tokenizer.json), see skill primitive-hf-bridge.
-
Do not silently fall through to a partial download or a stale cache. Halt and ask.
Required files for offline mode
Minimum:
config.json
model.safetensors (or sharded model-NNNNN-of-NNNNN.safetensors + model.safetensors.index.json)
- Tokenizer files:
tokenizer.json (preferred) or tokenizer.model + tokenizer_config.json.
Optional:
generation_config.json
special_tokens_map.json
Mapping conventions
The mapping table from HF names to curryTrain internal names lives in curry_train/models/<name>/checkpoint.py. It is per model because HF naming is non-uniform across architectures.
Typical Llama-style mapping:
"model.embed_tokens.weight" -> "tok_emb.weight"
"model.layers.{i}.self_attn.q_proj.weight" -> "blocks.{i}.attn.q.weight"
"model.layers.{i}.self_attn.k_proj.weight" -> "blocks.{i}.attn.k.weight"
"model.layers.{i}.self_attn.v_proj.weight" -> "blocks.{i}.attn.v.weight"
"model.layers.{i}.self_attn.o_proj.weight" -> "blocks.{i}.attn.o.weight"
"model.layers.{i}.mlp.gate_proj.weight" -> "blocks.{i}.mlp.w1.weight"
"model.layers.{i}.mlp.up_proj.weight" -> "blocks.{i}.mlp.w3.weight"
"model.layers.{i}.mlp.down_proj.weight" -> "blocks.{i}.mlp.w2.weight"
"model.layers.{i}.input_layernorm.weight" -> "blocks.{i}.attn_norm.weight"
"model.layers.{i}.post_attention_layernorm.weight" -> "blocks.{i}.mlp_norm.weight"
"model.norm.weight" -> "final_norm.weight"
"lm_head.weight" -> "output_head.weight"
Boundaries
- Bridge does not convert tokenizers — pass them through HF's native loaders.
- Bridge does not automatically handle quantization (4-bit / GPTQ); pre-quantize then convert.
- For sharded checkpoints, bridge respects the index file and reads shards on demand.
Implementation status
V1: stub at template/curry_train/primitives/hf_bridge.py. Reference: HuggingFace transformers.Auto* + safetensors.
Related
skills/new-experiment — calls bridge when --from=<hf-path> is provided.
skills/primitive-distributed-optimizer — interaction with sharded loading.
- HuggingFace docs for
huggingface-cli download.