The exporter converts HuggingFace Llama-format model checkpoints into LEAP's optimized binary format for the inference engine. It supports both full-precision (FP32) and quantized (INT8) export.
| File | Purpose |
|---|---|
main.cpp |
CLI entry point — parses args, invokes loader + exporter |
Loader.h/cpp |
Reads .safetensors files → LibTorch tensors, applies RoPE permutation |
Export.h/cpp |
Serializes model to LEAP binary format (FP32 or INT8) |
Utils.h/cpp |
Conversion utilities (BF16→FP32, byte-swapping) |
This function orchestrates the full model loading process:
-
Parse
params.json— Reads model hyperparameters (dim,n_layers,n_heads,n_kv_heads,vocab_size, etc.) from the model directory. -
Discover Shards — Scans for
*.safetensorsfiles and sorts them, supporting both single-file and multi-shard checkpoints. -
Load Tensors — For each shard:
- Uses
safetensors::mmap_from_file()for zero-copy reads. - Maps safetensors dtypes to
torch::ScalarType. - Constructs
torch::Tensorviews over the mmapped data. - Automatically converts BF16 tensors to FP32 via
Utils::bf16_to_fp32().
- Uses
-
Weight Assignment — Maps tensor names to model parameters:
model.embed_tokens.weight→tok_embeddingsmodel.layers.{L}.self_attn.{q,k,v,o}_proj.weight→ Attention weightsmodel.layers.{L}.mlp.{gate,up,down}_proj.weight→ FFN weightsmodel.layers.{L}.input_layernorm.weight→ Attention normmodel.layers.{L}.post_attention_layernorm.weight→ FFN normmodel.norm.weight→ Final RMSNormlm_head.weight→ Output projection
-
RoPE Permutation — Applies
permute_reverse()to WQ and WK weight matrices to match the inference engine's expected interleaved RoPE layout:[dim, dim] → reshape to [n_heads, dim/n_heads/2, 2, dim] → permute(0, 2, 1, 3) → reshape back
Loads a single .safetensors file using the safetensors-cpp library:
- Memory-maps the file for zero-copy access.
- Iterates over all tensors in the file.
- Returns a
std::map<std::string, torch::Tensor>.
Writes the model in full 32-bit floating point precision.
Binary Layout:
Offset 0x00: Magic (int32) = 0x616B3432 ("ak42")
Offset 0x04: Version (int32) = 1
Offset 0x08: Config (28 bytes) = {dim, hidden_dim, n_layers, n_heads,
n_kv_heads, vocab_size, seq_len}
Offset 0x100: Weights start (256-byte aligned header)
Weight Order:
tok_embeddings—[vocab_size × dim]- Per-layer weights (repeated
n_layerstimes):attention_norm—[dim]wq, wk, wv, wo— Attention weight matricesffn_norm—[dim]w1, w2, w3— FFN weight matrices
final_norm—[dim]output(classifier) —[vocab_size × dim](omitted if shared with embeddings)
Quantizes weights to symmetric INT8 for 4× memory reduction.
Binary Layout:
Offset 0x00: Magic (int32) = 0x616B3432
Offset 0x04: Version (int32) = 2
Offset 0x08: Config (28 bytes)
Offset 0x24: SharedClassifier (u8) = 0 or 1
Offset 0x25: GroupSize (int32) = 64 (default)
Offset 0x100: Weights start (256-byte aligned)
Quantization Scheme:
- Block-wise Symmetric Quantization with configurable
group_size(default: 64). - If
dim % 64 != 0, falls back togroup_size = 32. - Each block stores:
int8_t[group_size]— Quantized weightsfloat— Scale factor per block
What Gets Quantized:
- All weight matrices (Q, K, V, O, W1, W2, W3, embeddings, output)
- Normalization weights (RMSNorm) — kept in FP32 for numerical stability
Pipeline Optimization: The INT8 export uses a lookahead pipeline:
- Async Quantize: Fires off quantization of the next tensor on a background thread (
std::async). - Sync Write: Writes the previously quantized tensor to disk.
This overlaps CPU-bound quantization with I/O-bound disk writes for maximum export speed.
./export <output_path> --meta-llama <model_dir> [--version <1|2>]| Argument | Description |
|---|---|
output_path |
Destination path for the .bin file |
--meta-llama |
Path to directory containing params.json and .safetensors |
--version 1 |
FP32 export (default) |
--version 2 |
INT8 quantized export |
Example:
# Export Llama-3-70B to INT8
./export llama3-70b-q8.bin --meta-llama /models/Meta-Llama-3-70B --version 2