Text Generation
Transformers
Safetensors
PyTorch
English
laneformer
causal-lm
delayed-tensor-parallelism
dtp
conversational
custom_code
Eval Results
Instructions to use kogai/laneformer-2b-it with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use kogai/laneformer-2b-it with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="kogai/laneformer-2b-it", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("kogai/laneformer-2b-it", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use kogai/laneformer-2b-it with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "kogai/laneformer-2b-it" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kogai/laneformer-2b-it", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/kogai/laneformer-2b-it
- SGLang
How to use kogai/laneformer-2b-it with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "kogai/laneformer-2b-it" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kogai/laneformer-2b-it", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "kogai/laneformer-2b-it" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kogai/laneformer-2b-it", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use kogai/laneformer-2b-it with Docker Model Runner:
docker model run hf.co/kogai/laneformer-2b-it
Publich Laneformer 1B instruct
Browse files- LICENSE +1 -1
- README.md +197 -163
- __init__.py +7 -7
- config.json +8 -8
- configuration_laneformer.py +3 -3
- modeling_laneformer.py +27 -28
- tokenizer_config.json +2 -2
- torchtitan_metadata.json +2 -2
LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
Kog
|
| 2 |
=========================================
|
| 3 |
|
| 4 |
This repository contains materials under different licenses.
|
|
|
|
| 1 |
+
Kog Laneformer Repository License Notice
|
| 2 |
=========================================
|
| 3 |
|
| 4 |
This repository contains materials under different licenses.
|
README.md
CHANGED
|
@@ -29,7 +29,7 @@ datasets:
|
|
| 29 |
- nvidia/Nemotron-CC-v2
|
| 30 |
- nvidia/Nemotron-Pretraining-SFT-v1
|
| 31 |
- nvidia/Nemotron-Pretraining-Code-v1
|
| 32 |
-
model_type:
|
| 33 |
parameters: 2B
|
| 34 |
widget:
|
| 35 |
- text: "Explain the A* algorithm in details, then write a full Python implementation from scratch."
|
|
@@ -43,11 +43,11 @@ widget:
|
|
| 43 |
|
| 44 |
# Kog Laneformer 2B
|
| 45 |
|
| 46 |
-
Kog Laneformer 2B is a
|
| 47 |
|
| 48 |
-
The model is intended to make our Laneformer architecture available
|
| 49 |
|
| 50 |
-
Those
|
| 51 |
|
| 52 |
For background, see:
|
| 53 |
|
|
@@ -56,59 +56,50 @@ For background, see:
|
|
| 56 |
|
| 57 |
> **Custom code notice:** this model architecture is not currently part of upstream Transformers. Loading with `AutoConfig`, `AutoModel`, or `AutoModelForCausalLM` requires `trust_remote_code=True`. For production or security-sensitive use, review the modeling code and pin a specific Hub commit hash with `revision="<commit-hash>"`.
|
| 58 |
|
| 59 |
-
## Why this model exists
|
| 60 |
|
| 61 |
-
Many LLM serving systems optimize aggregate throughput across many concurrent requests. Our Laneformer
|
| 62 |
|
| 63 |
At batch size 1, autoregressive decoding is often constrained by memory bandwidth, synchronization, kernel launch overheads, and communication latency rather than raw FLOPs. Laneformer uses a lane-structured architecture and delayed communication pattern so tensor-parallel work can be organized around the latency structure of full-node GPU inference.
|
| 64 |
|
| 65 |
-
##
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
|
| 72 |
-
|
|
| 73 |
-
|
|
| 74 |
-
|
|
| 75 |
-
|
|
| 76 |
-
|
|
| 77 |
-
|
|
| 78 |
-
|
|
| 79 |
-
|
|
| 80 |
-
|
|
| 81 |
-
|
|
| 82 |
-
|
|
| 83 |
-
|
|
| 84 |
-
|
|
| 85 |
-
| Sliding window
|
| 86 |
-
| Sliding-window layers
|
| 87 |
-
| Full-attention layers
|
| 88 |
-
|
|
| 89 |
-
|
|
| 90 |
-
|
|
| 91 |
-
|
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
This release candidate uses:
|
| 98 |
-
|
| 99 |
-
- 8 lanes.
|
| 100 |
-
- Broadcast delay of 2.
|
| 101 |
-
- Grouped-query attention with 32 query heads and 16 KV heads.
|
| 102 |
-
- RoPE positional embeddings.
|
| 103 |
-
- 10 sliding-window attention layers followed by 5 full-attention layers.
|
| 104 |
-
- A vocab-parallel language-modeling head.
|
| 105 |
-
- Llama 2 tokenizer vocabulary and special-token convention.
|
| 106 |
|
| 107 |
The Hugging Face implementation is a reference/compatibility implementation. It is useful for loading, generation, inspection, and downstream experimentation, but it is not the same execution path as our production inference engine, which uses a latency-optimized runtime and low-level GPU kernels optimization.
|
| 108 |
|
| 109 |
-
#
|
| 110 |
|
| 111 |
-
##
|
| 112 |
|
| 113 |
```bash
|
| 114 |
uv venv --python 3.12
|
|
@@ -117,7 +108,7 @@ uv pip install torch --index-url https://download.pytorch.org/whl/cu130
|
|
| 117 |
uv pip install "transformers>=4.57.1" accelerate safetensors sentencepiece protobuf
|
| 118 |
```
|
| 119 |
|
| 120 |
-
##
|
| 121 |
|
| 122 |
```bash
|
| 123 |
uv venv --python 3.12
|
|
@@ -126,19 +117,21 @@ uv pip install torch --index-url https://download.pytorch.org/whl/rocm7.2
|
|
| 126 |
uv pip install "transformers>=4.57.1" accelerate safetensors sentencepiece protobuf
|
| 127 |
```
|
| 128 |
|
| 129 |
-
#
|
|
|
|
|
|
|
| 130 |
|
| 131 |
```python
|
| 132 |
import torch
|
| 133 |
from transformers import AutoModelForCausalLM, AutoTokenizer, set_seed
|
| 134 |
|
| 135 |
model_id = "kogai/laneformer-2b-it"
|
| 136 |
-
revision = "main"
|
| 137 |
seed = 42
|
| 138 |
temperature = 0.8
|
| 139 |
|
|
|
|
| 140 |
set_seed(seed)
|
| 141 |
-
print(f"Using random seed {seed}.")
|
| 142 |
|
| 143 |
print(f"Loading tokenizer for {model_id} ({revision=})...")
|
| 144 |
tokenizer = AutoTokenizer.from_pretrained(
|
|
@@ -146,7 +139,6 @@ tokenizer = AutoTokenizer.from_pretrained(
|
|
| 146 |
trust_remote_code=True,
|
| 147 |
revision=revision,
|
| 148 |
)
|
| 149 |
-
print("Tokenizer loaded.")
|
| 150 |
|
| 151 |
print("Loading model. This may take a few minutes on first run while files download...")
|
| 152 |
model = AutoModelForCausalLM.from_pretrained(
|
|
@@ -156,6 +148,7 @@ model = AutoModelForCausalLM.from_pretrained(
|
|
| 156 |
dtype="bfloat16",
|
| 157 |
device_map="auto",
|
| 158 |
)
|
|
|
|
| 159 |
print(f"Model loaded on {model.device}.")
|
| 160 |
|
| 161 |
# The Llama 2 tokenizer has no native pad token. If this repo sets PAD to EOS,
|
|
@@ -164,19 +157,22 @@ if tokenizer.pad_token is None:
|
|
| 164 |
tokenizer.pad_token = tokenizer.eos_token
|
| 165 |
print("Tokenizer had no pad token; using EOS as the pad token.")
|
| 166 |
|
| 167 |
-
|
| 168 |
-
|
|
|
|
|
|
|
|
|
|
| 169 |
]
|
| 170 |
|
| 171 |
print("\nPrompt:")
|
| 172 |
-
print(
|
| 173 |
-
print("\
|
| 174 |
-
inputs = tokenizer(
|
| 175 |
-
|
|
|
|
|
|
|
| 176 |
return_tensors="pt",
|
| 177 |
-
|
| 178 |
-
truncation=True,
|
| 179 |
-
max_length=4096,
|
| 180 |
).to(model.device)
|
| 181 |
print(f"Prompt token count: {inputs.input_ids.shape[-1]}")
|
| 182 |
|
|
@@ -198,116 +194,144 @@ print("-" * 80)
|
|
| 198 |
print(tokenizer.batch_decode(generated, skip_special_tokens=True)[0])
|
| 199 |
```
|
| 200 |
|
| 201 |
-
##
|
| 202 |
|
| 203 |
-
|
| 204 |
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
revision=commit_hash,
|
| 211 |
-
dtype="auto",
|
| 212 |
-
device_map="auto",
|
| 213 |
-
)
|
| 214 |
-
```
|
| 215 |
|
| 216 |
-
|
| 217 |
|
| 218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
|
| 220 |
-
|
| 221 |
-
|---|---:|
|
| 222 |
-
| `<unk>` | 0 |
|
| 223 |
-
| `<s>` | 1 |
|
| 224 |
-
| `</s>` | 2 |
|
| 225 |
|
| 226 |
-
|
| 227 |
|
| 228 |
-
|
|
|
|
|
|
|
| 229 |
|
| 230 |
-
|
| 231 |
|
| 232 |
-
##
|
| 233 |
|
| 234 |
-
| Stage
|
| 235 |
-
|---|---|---|---:|---:|---:|---|
|
| 236 |
-
| Pre-training
|
| 237 |
-
| Mid-training
|
| 238 |
-
| Post-training | SFT, instruction tuning | Hugging Face Transformers |
|
| 239 |
|
| 240 |
-
##
|
| 241 |
|
| 242 |
Both TorchTitan stages depend primarily on [NVIDIA Nemotron pre-training datasets](https://huggingface.co/collections/nvidia/nemotron-pre-training-datasets). Pre-training uses a Nemotron-CC-v2-centered mixture for broad language-model pretraining, with web, synthetic web, QA, math, SFT-style, and code components. Mid-training continues from the pre-training checkpoint on a more code- and reasoning-heavy Nemotron-derived mixture, increasing the emphasis on code metadata, synthetic code data, Common Crawl code pages, math, STEM, and reasoning data.
|
| 243 |
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
|
| 247 |
-
|
|
| 248 |
-
|
|
| 249 |
-
|
|
| 250 |
-
|
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
|
| 255 |
-
|
|
| 256 |
-
|
|
| 257 |
-
|
|
| 258 |
-
|
|
| 259 |
-
|
|
| 260 |
-
|
| 261 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
|
| 263 |
Kog Inference Engine running the Laneformer 2B model public-preview numbers:
|
| 264 |
|
| 265 |
-
| Setting
|
| 266 |
-
|---|---:|---|
|
| 267 |
-
| 8x AMD MI300X
|
| 268 |
| 8x NVIDIA H200 | 2,100 output tokens/s/request | FP16, batch size 1, no speculative decoding |
|
| 269 |
|
| 270 |
These benchmark numbers are for Kog's optimized inference stack, not the plain Hugging Face Transformers implementation in this repository. This preview does not rely on quantization, speculative decoding, pruning, early exit, or KV-cache compression to reach this speed.
|
| 271 |
|
| 272 |
## Evaluation
|
| 273 |
|
| 274 |
-
The following internal Kog evaluations were run in June 2026
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
|
| 283 |
-
|
|
| 284 |
-
|
|
| 285 |
-
|
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
|
| 301 |
-
|
|
| 302 |
-
| NIAH
|
| 303 |
-
| NIAH
|
| 304 |
-
|
|
| 305 |
-
|
|
| 306 |
-
|
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
|
| 312 |
This model is intended for:
|
| 313 |
|
|
@@ -319,14 +343,16 @@ This model is intended for:
|
|
| 319 |
|
| 320 |
This model is not automatically suitable for high-stakes settings such as medical, legal, financial, employment, education, public-sector, law-enforcement, or safety-critical decision-making.
|
| 321 |
|
| 322 |
-
#
|
| 323 |
|
| 324 |
-
Do not use this model or tokenizer in ways that violate the repository licenses, the Llama 2 Community License, the Llama 2 Acceptable Use Policy, applicable law, privacy rights, or safety policies.
|
| 325 |
|
| 326 |
-
|
|
|
|
|
|
|
| 327 |
|
| 328 |
- This is a 2B-class model and is not a frontier general-purpose assistant.
|
| 329 |
-
- The model is mid-trained and post-trained for code generation
|
| 330 |
- The model may generate incorrect, insecure, biased, toxic, or misleading content.
|
| 331 |
- The model may hallucinate facts, APIs, package names, citations, and code behavior.
|
| 332 |
- The base model may not follow instructions reliably unless it has been instruction-tuned.
|
|
@@ -334,17 +360,17 @@ Do not use this model or tokenizer in ways that violate the repository licenses,
|
|
| 334 |
- Performance may depend on the exact PyTorch, Transformers, device, dtype, and attention backend used.
|
| 335 |
- Because this repo uses custom code, downstream users should review code before execution and pin a revision in production.
|
| 336 |
|
| 337 |
-
#
|
| 338 |
|
| 339 |
This repository is **multi-license**.
|
| 340 |
|
| 341 |
-
##
|
| 342 |
|
| 343 |
Unless a file states otherwise, the model weights, Hugging Face custom modeling and configuration code, model configuration files, metadata files, documentation, and README/model card are released under the **Apache License 2.0**.
|
| 344 |
|
| 345 |
See [`LICENSE`](./LICENSE) for the full Apache License 2.0 text.
|
| 346 |
|
| 347 |
-
##
|
| 348 |
|
| 349 |
The tokenizer files are based on the **Llama 2 tokenizer** and are not licensed under Apache License 2.0. These tokenizer materials include, without limitation:
|
| 350 |
|
|
@@ -362,19 +388,27 @@ Required Llama 2 attribution notice:
|
|
| 362 |
|
| 363 |
Users and redistributors are responsible for complying with the Llama 2 Community License and its Acceptable Use Policy.
|
| 364 |
|
| 365 |
-
#
|
| 366 |
|
| 367 |
-
If you use this model or architecture, please cite the model repository and the Kog technical
|
| 368 |
|
| 369 |
```bibtex
|
| 370 |
-
@misc{
|
| 371 |
-
title = {Kog Laneformer 2B},
|
| 372 |
-
author = {Kog
|
| 373 |
year = {2026},
|
| 374 |
publisher = {Hugging Face},
|
| 375 |
howpublished = {\url{https://huggingface.co/kogai/laneformer-2b-it}}
|
| 376 |
}
|
| 377 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
@misc{kog_real_time_llm_inference_2026,
|
| 379 |
title = {Real-time LLM Inference on Standard Datacenter GPUs (3,000 tokens/s per request)},
|
| 380 |
author = {Kog Team},
|
|
@@ -390,6 +424,6 @@ If you use this model or architecture, please cite the model repository and the
|
|
| 390 |
}
|
| 391 |
```
|
| 392 |
|
| 393 |
-
#
|
| 394 |
|
| 395 |
For questions about this model, open a discussion or issue on the Hugging Face repository, or contact Kog AI through the channels listed on [kog.ai](https://www.kog.ai/).
|
|
|
|
| 29 |
- nvidia/Nemotron-CC-v2
|
| 30 |
- nvidia/Nemotron-Pretraining-SFT-v1
|
| 31 |
- nvidia/Nemotron-Pretraining-Code-v1
|
| 32 |
+
model_type: laneformer
|
| 33 |
parameters: 2B
|
| 34 |
widget:
|
| 35 |
- text: "Explain the A* algorithm in details, then write a full Python implementation from scratch."
|
|
|
|
| 43 |
|
| 44 |
# Kog Laneformer 2B
|
| 45 |
|
| 46 |
+
Kog Laneformer 2B is a latency-oriented Transformer variant built using **Delayed Tensor Parallelism (DTP)** to overlap tensor-parallel communication with useful computation and weight streaming.
|
| 47 |
|
| 48 |
+
The model is intended to make our Laneformer architecture available on Hugging Face for research, inspection, and fine-tuning. It is also the architecture family used in our public inference-engine preview, where single-request decoding speeds are **3,000 output tokens/s per request on 8x AMD MI300X** and **2,100 output tokens/s per request on 8x NVIDIA H200** in FP16 without speculative decoding.
|
| 49 |
|
| 50 |
+
Those figures are **Kog Inference Engine (KIE) benchmark results**, not expected performance from the generic Transformers runtime.
|
| 51 |
|
| 52 |
For background, see:
|
| 53 |
|
|
|
|
| 56 |
|
| 57 |
> **Custom code notice:** this model architecture is not currently part of upstream Transformers. Loading with `AutoConfig`, `AutoModel`, or `AutoModelForCausalLM` requires `trust_remote_code=True`. For production or security-sensitive use, review the modeling code and pin a specific Hub commit hash with `revision="<commit-hash>"`.
|
| 58 |
|
| 59 |
+
### Why this model exists
|
| 60 |
|
| 61 |
+
Many LLM serving systems optimize aggregate throughput across many concurrent requests. Our Laneformer work targets a different regime: **low-batch, single-request decode speed**, which is important for agentic coding loops, real-time copilots, voice assistants, and other sequential workflows where each generated step gates the next one.
|
| 62 |
|
| 63 |
At batch size 1, autoregressive decoding is often constrained by memory bandwidth, synchronization, kernel launch overheads, and communication latency rather than raw FLOPs. Laneformer uses a lane-structured architecture and delayed communication pattern so tensor-parallel work can be organized around the latency structure of full-node GPU inference.
|
| 64 |
|
| 65 |
+
### Architecture overview
|
| 66 |
+
|
| 67 |
+
Laneformer follows a Llama-style decoder-only architecture, but restructures tensor-parallel communication around **lanes**.
|
| 68 |
+
|
| 69 |
+
In standard tensor parallelism, each attention or MLP block typically requires communication before downstream computation can proceed. In **Delayed Tensor Parallelism (DTP)**, local outputs are communicated asynchronously and consumed several modules later, allowing communication latency to be hidden behind subsequent computation and weight streaming.
|
| 70 |
+
|
| 71 |
+
| Field | Value |
|
| 72 |
+
| ----------------------------- | ------------------------------------: |
|
| 73 |
+
| Model family | Laneformer |
|
| 74 |
+
| HF model type | `laneformer` |
|
| 75 |
+
| Architecture class | `LaneformerForCausalLM` |
|
| 76 |
+
| Task | Decoder-only causal language modeling |
|
| 77 |
+
| Parameters | ~2.3B |
|
| 78 |
+
| Hidden size | 3072 |
|
| 79 |
+
| Intermediate size | 12288 |
|
| 80 |
+
| MLP type | SwiGLU |
|
| 81 |
+
| Decoder layers | 15 |
|
| 82 |
+
| Attention heads | 32 |
|
| 83 |
+
| KV heads | 16 |
|
| 84 |
+
| Context length | 4096 tokens |
|
| 85 |
+
| Sliding window | 2048 tokens |
|
| 86 |
+
| Sliding-window layers | 0-9 |
|
| 87 |
+
| Full-attention layers | 10-14 |
|
| 88 |
+
| Vocabulary size | 32000 |
|
| 89 |
+
| Tokenizer | Llama 2 tokenizer |
|
| 90 |
+
| Number of lanes | 8 |
|
| 91 |
+
| DTP / Broadcast delay | 2 |
|
| 92 |
+
| LM head type | `vocab_parallel` |
|
| 93 |
+
| RoPE theta | 10000 |
|
| 94 |
+
| Tied word embeddings | false |
|
| 95 |
+
| Expected Transformers version | `>=4.57.1` |
|
| 96 |
+
| Published weight dtype | BFloat16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
The Hugging Face implementation is a reference/compatibility implementation. It is useful for loading, generation, inspection, and downstream experimentation, but it is not the same execution path as our production inference engine, which uses a latency-optimized runtime and low-level GPU kernels optimization.
|
| 99 |
|
| 100 |
+
# Installation
|
| 101 |
|
| 102 |
+
## Nvidia
|
| 103 |
|
| 104 |
```bash
|
| 105 |
uv venv --python 3.12
|
|
|
|
| 108 |
uv pip install "transformers>=4.57.1" accelerate safetensors sentencepiece protobuf
|
| 109 |
```
|
| 110 |
|
| 111 |
+
## AMD
|
| 112 |
|
| 113 |
```bash
|
| 114 |
uv venv --python 3.12
|
|
|
|
| 117 |
uv pip install "transformers>=4.57.1" accelerate safetensors sentencepiece protobuf
|
| 118 |
```
|
| 119 |
|
| 120 |
+
# Usage
|
| 121 |
+
|
| 122 |
+
This repository includes `chat_template.jinja`; use `tokenizer.apply_chat_template` for chat and instruction prompts.
|
| 123 |
|
| 124 |
```python
|
| 125 |
import torch
|
| 126 |
from transformers import AutoModelForCausalLM, AutoTokenizer, set_seed
|
| 127 |
|
| 128 |
model_id = "kogai/laneformer-2b-it"
|
| 129 |
+
revision = "main" # this model uses remote custom code, pin a reviewed commit hash for reproducible and safer usage
|
| 130 |
seed = 42
|
| 131 |
temperature = 0.8
|
| 132 |
|
| 133 |
+
print(f"Using random seed {seed}.")
|
| 134 |
set_seed(seed)
|
|
|
|
| 135 |
|
| 136 |
print(f"Loading tokenizer for {model_id} ({revision=})...")
|
| 137 |
tokenizer = AutoTokenizer.from_pretrained(
|
|
|
|
| 139 |
trust_remote_code=True,
|
| 140 |
revision=revision,
|
| 141 |
)
|
|
|
|
| 142 |
|
| 143 |
print("Loading model. This may take a few minutes on first run while files download...")
|
| 144 |
model = AutoModelForCausalLM.from_pretrained(
|
|
|
|
| 148 |
dtype="bfloat16",
|
| 149 |
device_map="auto",
|
| 150 |
)
|
| 151 |
+
model.eval()
|
| 152 |
print(f"Model loaded on {model.device}.")
|
| 153 |
|
| 154 |
# The Llama 2 tokenizer has no native pad token. If this repo sets PAD to EOS,
|
|
|
|
| 157 |
tokenizer.pad_token = tokenizer.eos_token
|
| 158 |
print("Tokenizer had no pad token; using EOS as the pad token.")
|
| 159 |
|
| 160 |
+
messages = [
|
| 161 |
+
{
|
| 162 |
+
"role": "user",
|
| 163 |
+
"content": "Explain how a binary heap works, then write a complete min-heap implementation from scratch in Python.",
|
| 164 |
+
},
|
| 165 |
]
|
| 166 |
|
| 167 |
print("\nPrompt:")
|
| 168 |
+
print(messages[0]["content"])
|
| 169 |
+
print("\nApplying chat template...")
|
| 170 |
+
inputs = tokenizer.apply_chat_template(
|
| 171 |
+
messages,
|
| 172 |
+
add_generation_prompt=True,
|
| 173 |
+
tokenize=True,
|
| 174 |
return_tensors="pt",
|
| 175 |
+
return_dict=True,
|
|
|
|
|
|
|
| 176 |
).to(model.device)
|
| 177 |
print(f"Prompt token count: {inputs.input_ids.shape[-1]}")
|
| 178 |
|
|
|
|
| 194 |
print(tokenizer.batch_decode(generated, skip_special_tokens=True)[0])
|
| 195 |
```
|
| 196 |
|
| 197 |
+
## Tokenizer & Chat template
|
| 198 |
|
| 199 |
+
This repository uses the **Llama 2 tokenizer** with a 32,000-token vocabulary. The expected special-token convention is:
|
| 200 |
|
| 201 |
+
| Token | ID |
|
| 202 |
+
| ------- | --: |
|
| 203 |
+
| `<unk>` | 0 |
|
| 204 |
+
| `<s>` | 1 |
|
| 205 |
+
| `</s>` | 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
|
| 207 |
+
Instruction-tuned models in this family, such as `kogai/laneformer-2b-it`, include a repository-level `chat_template.jinja`.
|
| 208 |
|
| 209 |
+
For the current instruction-tuned template:
|
| 210 |
+
|
| 211 |
+
- Only `user` and `assistant` roles are supported.
|
| 212 |
+
- System messages are ignored.
|
| 213 |
+
- Each user or assistant message is formatted with a Llama-3-style role header, followed by trimmed message content and `</s>`.
|
| 214 |
+
|
| 215 |
+
Usage:
|
| 216 |
+
|
| 217 |
+
```python
|
| 218 |
+
messages = [
|
| 219 |
+
{
|
| 220 |
+
"role": "user",
|
| 221 |
+
"content": "Explain how a binary heap works, then write a complete min-heap implementation from scratch in Python.",
|
| 222 |
+
},
|
| 223 |
+
]
|
| 224 |
+
|
| 225 |
+
inputs = tokenizer.apply_chat_template(
|
| 226 |
+
messages,
|
| 227 |
+
add_generation_prompt=True,
|
| 228 |
+
tokenize=True,
|
| 229 |
+
return_tensors="pt",
|
| 230 |
+
return_dict=True,
|
| 231 |
+
).to(model.device)
|
| 232 |
+
```
|
| 233 |
|
| 234 |
+
# Training data and procedure
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
|
| 236 |
+
Laneformer 2B was trained with a staged language-modeling recipe:
|
| 237 |
|
| 238 |
+
1. Broad pre-training to build general language-modeling capabilities.
|
| 239 |
+
2. Code- and reasoning-heavy continuation training.
|
| 240 |
+
3. Lightweight post-training to produce the released instruction-tuned model.
|
| 241 |
|
| 242 |
+
The TorchTitan training stages used sequence length 4,096 and global batch size 1,536, or approximately 6.29M tokens per optimizer step.
|
| 243 |
|
| 244 |
+
## Training stages
|
| 245 |
|
| 246 |
+
| Stage | Focus | Framework | Tokens | Steps | Approx. tokens / step | Notes |
|
| 247 |
+
| ------------- | ---------------------------------------- | ------------------------- | -----: | ------: | --------------------: | ------------------------------------------------------------------------------- |
|
| 248 |
+
| Pre-training | Broad language-model pre-training | TorchTitan | ~4T | 620,000 | ~6.29M | Nemotron-derived broad mixture; final checkpoint selected. |
|
| 249 |
+
| Mid-training | Code- and reasoning-focused continuation | TorchTitan | ~2T | 310,000 | ~6.29M | Continued from the pre-training checkpoint with a code/reasoning-heavy mixture. |
|
| 250 |
+
| Post-training | SFT, instruction tuning, identity tuning | Hugging Face Transformers | ~210M | 200 | ~1.05M | Lightweight custom data mixture initialized from the mid-training checkpoint. |
|
| 251 |
|
| 252 |
+
## Data sources
|
| 253 |
|
| 254 |
Both TorchTitan stages depend primarily on [NVIDIA Nemotron pre-training datasets](https://huggingface.co/collections/nvidia/nemotron-pre-training-datasets). Pre-training uses a Nemotron-CC-v2-centered mixture for broad language-model pretraining, with web, synthetic web, QA, math, SFT-style, and code components. Mid-training continues from the pre-training checkpoint on a more code- and reasoning-heavy Nemotron-derived mixture, increasing the emphasis on code metadata, synthetic code data, Common Crawl code pages, math, STEM, and reasoning data.
|
| 255 |
|
| 256 |
+
| Category | Pre-training / Phase 1 | Mid-training / Phase 2 | Notes |
|
| 257 |
+
| --------------------------- | ---------------------: | ---------------------: | ------------------------------------------------------------------------------------ |
|
| 258 |
+
| General / web crawl | 63.2% | 10.0% | Phase 2 keeps a smaller high-quality and synthetic web component. |
|
| 259 |
+
| Code | 21.0% | 59.01% | Large increase from code metadata, synthetic code data, and Common Crawl code pages. |
|
| 260 |
+
| Math / STEM / reasoning | 6.3% | 30.01% | Large increase from math, RQA, STEM, and textbook-like data. |
|
| 261 |
+
| Multilingual | 5.0% | 0.0% | Removed in the current Phase 2 mixture. |
|
| 262 |
+
| QA / instruction / academic | 4.5% | 1.0% | Only a small general SFT-style component remains. |
|
| 263 |
+
|
| 264 |
+
## Training infrastructure
|
| 265 |
+
|
| 266 |
+
| Field | Value |
|
| 267 |
+
| ------------------------------- | --------------------------------------------- |
|
| 268 |
+
| Pre-training framework | TorchTitan |
|
| 269 |
+
| Post-training framework | Hugging Face Transformers |
|
| 270 |
+
| Training hardware | 24 nodes × 8 NVIDIA H100 GPUs = 192 H100 GPUs |
|
| 271 |
+
| Training clusters | Scaleway cluster; ADASTRA cluster |
|
| 272 |
+
| Cloud/provider/region | France |
|
| 273 |
+
| Training time | ~21 days |
|
| 274 |
+
| Precision | FP32/BF16 mixed precision |
|
| 275 |
+
| Parallelism | FSDP |
|
| 276 |
+
| Optimizer | AdamW |
|
| 277 |
+
| Learning-rate schedule | WSD |
|
| 278 |
+
| Sequence length during training | 4096 |
|
| 279 |
+
| Checkpoint selection | final step |
|
| 280 |
+
|
| 281 |
+
# Inference and performance
|
| 282 |
|
| 283 |
Kog Inference Engine running the Laneformer 2B model public-preview numbers:
|
| 284 |
|
| 285 |
+
| Setting | Reported speed | Notes |
|
| 286 |
+
| -------------- | ----------------------------: | ------------------------------------------- |
|
| 287 |
+
| 8x AMD MI300X | 3,000 output tokens/s/request | FP16, batch size 1, no speculative decoding |
|
| 288 |
| 8x NVIDIA H200 | 2,100 output tokens/s/request | FP16, batch size 1, no speculative decoding |
|
| 289 |
|
| 290 |
These benchmark numbers are for Kog's optimized inference stack, not the plain Hugging Face Transformers implementation in this repository. This preview does not rely on quantization, speculative decoding, pruning, early exit, or KV-cache compression to reach this speed.
|
| 291 |
|
| 292 |
## Evaluation
|
| 293 |
|
| 294 |
+
The following internal Kog evaluations were run in June 2026 against a local Kog serving endpoint for the Laneformer 2B instruction-tuned checkpoint at batch size 1 in FP16. These values evaluate the served preview model; small numerical differences may appear when evaluating the BF16 Hugging Face checkpoint directly through a different runtime.
|
| 295 |
+
|
| 296 |
+
## Code generation
|
| 297 |
+
|
| 298 |
+
HumanEval+ and MBPP+ were evaluated with greedy decoding. Generation was performed through the Kog serving endpoint, scoring used EvalPlus.
|
| 299 |
+
|
| 300 |
+
A custom code-block selection step named `target_function` was applied before scoring. When possible, this step selects the code block containing the target function name before EvalPlus preprocessing.
|
| 301 |
+
|
| 302 |
+
| Benchmark | Metric | Value | Samples | Decoding | Scoring | Postprocessing |
|
| 303 |
+
| ---------- | -----: | ----: | ------: | ---------------------------------------- | -------- | --------------------------------- |
|
| 304 |
+
| HumanEval+ | pass@1 | 45.1 | 164 | Greedy, temperature=0, `do_sample=False` | EvalPlus | `target_function` block selection |
|
| 305 |
+
| MBPP+ | pass@1 | 51.6 | 378 | Greedy, temperature=0, `do_sample=False` | EvalPlus | `target_function` block selection |
|
| 306 |
+
|
| 307 |
+
## General multiple-choice checks
|
| 308 |
+
|
| 309 |
+
ARC-Challenge and ARC-Easy were evaluated with 0-shot multiple-choice logprobs. Orchestration used `lm-evaluation-harness` 0.4.12 against the Kog serving endpoint.
|
| 310 |
+
|
| 311 |
+
| Benchmark | Metric | Value | Samples | Setting |
|
| 312 |
+
| ------------- | ------------------: | ----: | ------: | ------------------------------------------ |
|
| 313 |
+
| ARC-Challenge | Normalized accuracy | 31.06 | 1,172 | 0-shot multiple-choice logprobs, `lm_eval` |
|
| 314 |
+
| ARC-Easy | Normalized accuracy | 47.90 | 2,376 | 0-shot multiple-choice logprobs, `lm_eval` |
|
| 315 |
+
|
| 316 |
+
## Long-context synthetic checks
|
| 317 |
+
|
| 318 |
+
Long-context checks were also run with RULER-style synthetic tasks at 2,048 and 4,096 tokens using 0-shot greedy chat generation using the LM Evaluation Harness framework. Values below are string-match scores.
|
| 319 |
+
|
| 320 |
+
| Task | 2,048 tokens | 4,096 tokens | Effective samples | Setting |
|
| 321 |
+
| ------------------------------- | -----------: | -----------: | ----------------: | --------------: |
|
| 322 |
+
| NIAH single 1 | 100.00 | 100.00 | 500 | using `lm_eval` |
|
| 323 |
+
| NIAH single 2 | 100.00 | 100.00 | 500 | using `lm_eval` |
|
| 324 |
+
| NIAH single 3 | 99.80 | 91.60 | 500 | using `lm_eval` |
|
| 325 |
+
| NIAH multikey 1 | 99.20 | 83.40 | 500 | using `lm_eval` |
|
| 326 |
+
| NIAH multikey 2 | 97.80 | 60.00 | 500 | using `lm_eval` |
|
| 327 |
+
| NIAH multikey 3 | 91.80 | 91.20 | 500 | using `lm_eval` |
|
| 328 |
+
| NIAH multiquery | 95.40 | 69.70 | 500 | using `lm_eval` |
|
| 329 |
+
| NIAH multivalue | 94.60 | 82.20 | 500 | using `lm_eval` |
|
| 330 |
+
| RULER variable tracking | 77.92 | 3.92 | 500 | using `lm_eval` |
|
| 331 |
+
| RULER common words extraction | 24.72 | 78.14 | 500 | using `lm_eval` |
|
| 332 |
+
| RULER frequent words extraction | 78.80 | 64.73 | 500 | using `lm_eval` |
|
| 333 |
+
|
| 334 |
+
# Intended use
|
| 335 |
|
| 336 |
This model is intended for:
|
| 337 |
|
|
|
|
| 343 |
|
| 344 |
This model is not automatically suitable for high-stakes settings such as medical, legal, financial, employment, education, public-sector, law-enforcement, or safety-critical decision-making.
|
| 345 |
|
| 346 |
+
# Out-of-scope use
|
| 347 |
|
| 348 |
+
Do not use this model or tokenizer in ways that violate the repository licenses, the Llama 2 Community License, the Llama 2 Acceptable Use Policy, applicable law, privacy rights, or safety policies.
|
| 349 |
|
| 350 |
+
Do not present generated outputs as factual without independent verification. Do not use the model as the sole decision-maker in high-stakes workflows.
|
| 351 |
+
|
| 352 |
+
# Limitations and risks
|
| 353 |
|
| 354 |
- This is a 2B-class model and is not a frontier general-purpose assistant.
|
| 355 |
+
- The model is primarily mid-trained and post-trained for code generation: it is not optimized as a broad general-purpose assistant.
|
| 356 |
- The model may generate incorrect, insecure, biased, toxic, or misleading content.
|
| 357 |
- The model may hallucinate facts, APIs, package names, citations, and code behavior.
|
| 358 |
- The base model may not follow instructions reliably unless it has been instruction-tuned.
|
|
|
|
| 360 |
- Performance may depend on the exact PyTorch, Transformers, device, dtype, and attention backend used.
|
| 361 |
- Because this repo uses custom code, downstream users should review code before execution and pin a revision in production.
|
| 362 |
|
| 363 |
+
# License
|
| 364 |
|
| 365 |
This repository is **multi-license**.
|
| 366 |
|
| 367 |
+
## Kog-owned materials: Apache License 2.0
|
| 368 |
|
| 369 |
Unless a file states otherwise, the model weights, Hugging Face custom modeling and configuration code, model configuration files, metadata files, documentation, and README/model card are released under the **Apache License 2.0**.
|
| 370 |
|
| 371 |
See [`LICENSE`](./LICENSE) for the full Apache License 2.0 text.
|
| 372 |
|
| 373 |
+
## Tokenizer materials: Llama 2 Community License
|
| 374 |
|
| 375 |
The tokenizer files are based on the **Llama 2 tokenizer** and are not licensed under Apache License 2.0. These tokenizer materials include, without limitation:
|
| 376 |
|
|
|
|
| 388 |
|
| 389 |
Users and redistributors are responsible for complying with the Llama 2 Community License and its Acceptable Use Policy.
|
| 390 |
|
| 391 |
+
# Citation
|
| 392 |
|
| 393 |
+
If you use this model or architecture, please cite the model repository and the relevant Kog technical posts:
|
| 394 |
|
| 395 |
```bibtex
|
| 396 |
+
@misc{kog_laneformer_2b_it_2026,
|
| 397 |
+
title = {Kog Laneformer 2B Instruct Model},
|
| 398 |
+
author = {Kog Team},
|
| 399 |
year = {2026},
|
| 400 |
publisher = {Hugging Face},
|
| 401 |
howpublished = {\url{https://huggingface.co/kogai/laneformer-2b-it}}
|
| 402 |
}
|
| 403 |
|
| 404 |
+
@online{kog_laneformer_2b_2026,
|
| 405 |
+
title = {{Laneformer 2B: The Latency-First Model Behind Kog Inference Engine}},
|
| 406 |
+
author = {Kog Team},
|
| 407 |
+
year = {2026},
|
| 408 |
+
url = {https://huggingface.co/blog/kogai/kog-laneformer-2b-the-latency-first-model}
|
| 409 |
+
note = {HuggingFace blog}
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
@misc{kog_real_time_llm_inference_2026,
|
| 413 |
title = {Real-time LLM Inference on Standard Datacenter GPUs (3,000 tokens/s per request)},
|
| 414 |
author = {Kog Team},
|
|
|
|
| 424 |
}
|
| 425 |
```
|
| 426 |
|
| 427 |
+
# Contact
|
| 428 |
|
| 429 |
For questions about this model, open a discussion or issue on the Hugging Face repository, or contact Kog AI through the channels listed on [kog.ai](https://www.kog.ai/).
|
__init__.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
from transformers import AutoConfig
|
| 2 |
|
| 3 |
-
from .configuration_laneformer import
|
| 4 |
-
from .modeling_laneformer import
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
AutoConfig.register("
|
| 10 |
|
| 11 |
-
__all__ = ["
|
|
|
|
| 1 |
from transformers import AutoConfig
|
| 2 |
|
| 3 |
+
from .configuration_laneformer import LaneformerConfig
|
| 4 |
+
from .modeling_laneformer import LaneformerForCausalLM, LaneformerModel
|
| 5 |
|
| 6 |
+
LaneformerConfig.register_for_auto_class()
|
| 7 |
+
LaneformerModel.register_for_auto_class("AutoModel")
|
| 8 |
+
LaneformerForCausalLM.register_for_auto_class("AutoModelForCausalLM")
|
| 9 |
+
AutoConfig.register("laneformer", LaneformerConfig)
|
| 10 |
|
| 11 |
+
__all__ = ["LaneformerConfig", "LaneformerModel", "LaneformerForCausalLM"]
|
config.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
| 1 |
{
|
| 2 |
-
"model_type": "
|
| 3 |
"architectures": [
|
| 4 |
-
"
|
| 5 |
],
|
| 6 |
"auto_map": {
|
| 7 |
-
"AutoConfig": "configuration_laneformer.
|
| 8 |
-
"AutoModel": "modeling_laneformer.
|
| 9 |
-
"AutoModelForCausalLM": "modeling_laneformer.
|
| 10 |
},
|
| 11 |
"hidden_size": 3072,
|
| 12 |
"num_hidden_layers": 15,
|
| 13 |
"num_attention_heads": 32,
|
| 14 |
"num_key_value_heads": 16,
|
| 15 |
"intermediate_size": 12288,
|
| 16 |
-
"max_position_embeddings":
|
| 17 |
-
"max_seq_len":
|
| 18 |
"eos_token_id": 2,
|
| 19 |
"pad_token_id": 2,
|
| 20 |
"vocab_size": 32000,
|
|
@@ -60,7 +60,7 @@
|
|
| 60 |
"full_attention",
|
| 61 |
"full_attention"
|
| 62 |
],
|
| 63 |
-
"_attn_implementation": "
|
| 64 |
"dtype": "bfloat16",
|
| 65 |
"transformers_version": "4.57.6"
|
| 66 |
}
|
|
|
|
| 1 |
{
|
| 2 |
+
"model_type": "laneformer",
|
| 3 |
"architectures": [
|
| 4 |
+
"LaneformerForCausalLM"
|
| 5 |
],
|
| 6 |
"auto_map": {
|
| 7 |
+
"AutoConfig": "configuration_laneformer.LaneformerConfig",
|
| 8 |
+
"AutoModel": "modeling_laneformer.LaneformerModel",
|
| 9 |
+
"AutoModelForCausalLM": "modeling_laneformer.LaneformerForCausalLM"
|
| 10 |
},
|
| 11 |
"hidden_size": 3072,
|
| 12 |
"num_hidden_layers": 15,
|
| 13 |
"num_attention_heads": 32,
|
| 14 |
"num_key_value_heads": 16,
|
| 15 |
"intermediate_size": 12288,
|
| 16 |
+
"max_position_embeddings": 4096,
|
| 17 |
+
"max_seq_len": 4096,
|
| 18 |
"eos_token_id": 2,
|
| 19 |
"pad_token_id": 2,
|
| 20 |
"vocab_size": 32000,
|
|
|
|
| 60 |
"full_attention",
|
| 61 |
"full_attention"
|
| 62 |
],
|
| 63 |
+
"_attn_implementation": "sdpa",
|
| 64 |
"dtype": "bfloat16",
|
| 65 |
"transformers_version": "4.57.6"
|
| 66 |
}
|
configuration_laneformer.py
CHANGED
|
@@ -121,8 +121,8 @@ def _validate_rope_scaling(rope_scaling: Optional[dict[str, Any]]) -> None:
|
|
| 121 |
raise ValueError("rope_scaling.original_max_position_embeddings must be > 0")
|
| 122 |
|
| 123 |
|
| 124 |
-
class
|
| 125 |
-
model_type = "
|
| 126 |
keys_to_ignore_at_inference = ["past_key_values"]
|
| 127 |
|
| 128 |
def __init__(
|
|
@@ -228,7 +228,7 @@ class LaneformerTPConfig(PretrainedConfig):
|
|
| 228 |
if sliding_window is not None:
|
| 229 |
sliding_window = _validate_positive_int("sliding_window", sliding_window)
|
| 230 |
if tie_word_embeddings:
|
| 231 |
-
raise ValueError("tie_word_embeddings is not supported for
|
| 232 |
_validate_rope_scaling(rope_scaling)
|
| 233 |
if swa_layers is None:
|
| 234 |
swa_layers = list(range(sliding_window_n_layers))
|
|
|
|
| 121 |
raise ValueError("rope_scaling.original_max_position_embeddings must be > 0")
|
| 122 |
|
| 123 |
|
| 124 |
+
class LaneformerConfig(PretrainedConfig):
|
| 125 |
+
model_type = "laneformer"
|
| 126 |
keys_to_ignore_at_inference = ["past_key_values"]
|
| 127 |
|
| 128 |
def __init__(
|
|
|
|
| 228 |
if sliding_window is not None:
|
| 229 |
sliding_window = _validate_positive_int("sliding_window", sliding_window)
|
| 230 |
if tie_word_embeddings:
|
| 231 |
+
raise ValueError("tie_word_embeddings is not supported for Laneformer")
|
| 232 |
_validate_rope_scaling(rope_scaling)
|
| 233 |
if swa_layers is None:
|
| 234 |
swa_layers = list(range(sliding_window_n_layers))
|
modeling_laneformer.py
CHANGED
|
@@ -2,9 +2,9 @@
|
|
| 2 |
Hugging Face-compatible Laneformer implementation.
|
| 3 |
|
| 4 |
This file defines:
|
| 5 |
-
-
|
| 6 |
-
-
|
| 7 |
-
-
|
| 8 |
|
| 9 |
It mirrors the TorchTitan Laneformer structure so that state_dict keys largely match,
|
| 10 |
which makes converting checkpoints trivial (often identity mapping).
|
|
@@ -35,7 +35,7 @@ from transformers.modeling_outputs import (
|
|
| 35 |
from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 36 |
from transformers.utils import auto_docstring, can_return_tuple, TransformersKwargs
|
| 37 |
|
| 38 |
-
from .configuration_laneformer import
|
| 39 |
|
| 40 |
|
| 41 |
# ============================================================
|
|
@@ -50,7 +50,7 @@ class RoPEScalingArgs:
|
|
| 50 |
|
| 51 |
|
| 52 |
def _rope_scaling_from_config(
|
| 53 |
-
config:
|
| 54 |
) -> RoPEScalingArgs | None:
|
| 55 |
if config.rope_scaling is None:
|
| 56 |
return None
|
|
@@ -295,7 +295,7 @@ def eager_attention_forward(
|
|
| 295 |
return attn_output, attn_weights
|
| 296 |
|
| 297 |
|
| 298 |
-
def _attention_interface(config:
|
| 299 |
attn_implementation = getattr(config, "_attn_implementation", "eager")
|
| 300 |
if attn_implementation == "eager":
|
| 301 |
return eager_attention_forward
|
|
@@ -319,7 +319,7 @@ def _call_attention_mask_factory(
|
|
| 319 |
mask_factory,
|
| 320 |
*,
|
| 321 |
uses_inputs_embeds: bool,
|
| 322 |
-
config:
|
| 323 |
inputs_embeds: torch.Tensor,
|
| 324 |
attention_mask: Optional[torch.Tensor],
|
| 325 |
cache_position: torch.Tensor,
|
|
@@ -386,7 +386,7 @@ def _apply_sliding_window_to_attention_mask(
|
|
| 386 |
|
| 387 |
|
| 388 |
def _layer_uses_sliding_window_attention(
|
| 389 |
-
config:
|
| 390 |
layer_index: int,
|
| 391 |
) -> bool:
|
| 392 |
sliding_window = getattr(config, "sliding_window", None)
|
|
@@ -409,7 +409,7 @@ def _layer_uses_sliding_window_attention(
|
|
| 409 |
|
| 410 |
|
| 411 |
def _layer_attention_masks_from_provided_mask(
|
| 412 |
-
config:
|
| 413 |
attention_mask: Optional[torch.Tensor],
|
| 414 |
) -> Optional[list[Optional[torch.Tensor]]]:
|
| 415 |
if not _attention_mask_needs_sliding_window_overlay(attention_mask):
|
|
@@ -471,7 +471,7 @@ class LaneModule:
|
|
| 471 |
class LaneformerAttention(LaneModule, nn.Module):
|
| 472 |
def __init__(
|
| 473 |
self,
|
| 474 |
-
config:
|
| 475 |
layer_idx: int,
|
| 476 |
reduce_mode: ReduceMode = ReduceMode.PRESENT,
|
| 477 |
):
|
|
@@ -580,7 +580,7 @@ class LaneformerAttention(LaneModule, nn.Module):
|
|
| 580 |
|
| 581 |
class LaneformerMLP(LaneModule, nn.Module):
|
| 582 |
def __init__(
|
| 583 |
-
self, config:
|
| 584 |
):
|
| 585 |
super().__init__(
|
| 586 |
no_reduce_scale=math.sqrt(config.num_lanes), reduce_mode=reduce_mode
|
|
@@ -600,7 +600,7 @@ class LaneformerMLP(LaneModule, nn.Module):
|
|
| 600 |
class LaneformerDecoderLayer(nn.Module):
|
| 601 |
def __init__(
|
| 602 |
self,
|
| 603 |
-
config:
|
| 604 |
layer_idx: int,
|
| 605 |
attention_reduce_mode: ReduceMode,
|
| 606 |
mlp_reduce_mode: ReduceMode,
|
|
@@ -667,12 +667,12 @@ class LaneformerDecoderLayer(nn.Module):
|
|
| 667 |
# Backbone & HF wrappers
|
| 668 |
# ============================================================
|
| 669 |
class LaneformerPreTrainedModel(PreTrainedModel):
|
| 670 |
-
config_class =
|
| 671 |
-
config:
|
| 672 |
base_model_prefix = "model"
|
| 673 |
supports_gradient_checkpointing = False
|
| 674 |
_no_split_modules = [
|
| 675 |
-
"
|
| 676 |
"LaneformerDecoderLayer",
|
| 677 |
"LaneformerAttention",
|
| 678 |
"LaneformerMLP",
|
|
@@ -681,11 +681,10 @@ class LaneformerPreTrainedModel(PreTrainedModel):
|
|
| 681 |
# Advertise support for Transformers attention backends (vLLM / flash / sdpa routing)
|
| 682 |
_supports_attention_backend = True
|
| 683 |
_supports_sdpa = True
|
| 684 |
-
_supports_flex_attn = True
|
| 685 |
|
| 686 |
|
| 687 |
-
class
|
| 688 |
-
def __init__(self, config:
|
| 689 |
super().__init__(config)
|
| 690 |
self.padding_idx = config.pad_token_id
|
| 691 |
self.config = config
|
|
@@ -911,14 +910,14 @@ class LaneformerTPModel(LaneformerPreTrainedModel):
|
|
| 911 |
|
| 912 |
|
| 913 |
@auto_docstring
|
| 914 |
-
class
|
| 915 |
_pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
|
| 916 |
|
| 917 |
-
def __init__(self, config:
|
| 918 |
super().__init__(config)
|
| 919 |
if config.tie_word_embeddings:
|
| 920 |
-
raise ValueError("tie_word_embeddings is not supported for
|
| 921 |
-
self.model =
|
| 922 |
self.vocab_size = config.vocab_size
|
| 923 |
self.lm_head_type = config.lm_head_type
|
| 924 |
if self.lm_head_type == "replicate":
|
|
@@ -979,15 +978,15 @@ class LaneformerTPForCausalLM(LaneformerPreTrainedModel, GenerationMixin):
|
|
| 979 |
**kwargs: Unpack[TransformersKwargs],
|
| 980 |
) -> CausalLMOutputWithPast:
|
| 981 |
r"""
|
| 982 |
-
Example with a tiny randomly initialized
|
| 983 |
|
| 984 |
```python
|
| 985 |
>>> import torch
|
| 986 |
-
>>> from torchtitan.models.
|
| 987 |
-
...
|
| 988 |
-
...
|
| 989 |
... )
|
| 990 |
-
>>> config =
|
| 991 |
... hidden_size=16,
|
| 992 |
... num_hidden_layers=2,
|
| 993 |
... num_attention_heads=4,
|
|
@@ -996,7 +995,7 @@ class LaneformerTPForCausalLM(LaneformerPreTrainedModel, GenerationMixin):
|
|
| 996 |
... vocab_size=64,
|
| 997 |
... num_lanes=2,
|
| 998 |
... )
|
| 999 |
-
>>> model =
|
| 1000 |
>>> input_ids = torch.tensor([[1, 2, 3]])
|
| 1001 |
>>> logits = model(input_ids=input_ids, use_cache=False).logits
|
| 1002 |
>>> logits.shape
|
|
|
|
| 2 |
Hugging Face-compatible Laneformer implementation.
|
| 3 |
|
| 4 |
This file defines:
|
| 5 |
+
- LaneformerPreTrainedModel
|
| 6 |
+
- LaneformerModel (backbone)
|
| 7 |
+
- LaneformerForCausalLM (head + loss)
|
| 8 |
|
| 9 |
It mirrors the TorchTitan Laneformer structure so that state_dict keys largely match,
|
| 10 |
which makes converting checkpoints trivial (often identity mapping).
|
|
|
|
| 35 |
from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
|
| 36 |
from transformers.utils import auto_docstring, can_return_tuple, TransformersKwargs
|
| 37 |
|
| 38 |
+
from .configuration_laneformer import LaneformerConfig
|
| 39 |
|
| 40 |
|
| 41 |
# ============================================================
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
def _rope_scaling_from_config(
|
| 53 |
+
config: LaneformerConfig,
|
| 54 |
) -> RoPEScalingArgs | None:
|
| 55 |
if config.rope_scaling is None:
|
| 56 |
return None
|
|
|
|
| 295 |
return attn_output, attn_weights
|
| 296 |
|
| 297 |
|
| 298 |
+
def _attention_interface(config: LaneformerConfig):
|
| 299 |
attn_implementation = getattr(config, "_attn_implementation", "eager")
|
| 300 |
if attn_implementation == "eager":
|
| 301 |
return eager_attention_forward
|
|
|
|
| 319 |
mask_factory,
|
| 320 |
*,
|
| 321 |
uses_inputs_embeds: bool,
|
| 322 |
+
config: LaneformerConfig,
|
| 323 |
inputs_embeds: torch.Tensor,
|
| 324 |
attention_mask: Optional[torch.Tensor],
|
| 325 |
cache_position: torch.Tensor,
|
|
|
|
| 386 |
|
| 387 |
|
| 388 |
def _layer_uses_sliding_window_attention(
|
| 389 |
+
config: LaneformerConfig,
|
| 390 |
layer_index: int,
|
| 391 |
) -> bool:
|
| 392 |
sliding_window = getattr(config, "sliding_window", None)
|
|
|
|
| 409 |
|
| 410 |
|
| 411 |
def _layer_attention_masks_from_provided_mask(
|
| 412 |
+
config: LaneformerConfig,
|
| 413 |
attention_mask: Optional[torch.Tensor],
|
| 414 |
) -> Optional[list[Optional[torch.Tensor]]]:
|
| 415 |
if not _attention_mask_needs_sliding_window_overlay(attention_mask):
|
|
|
|
| 471 |
class LaneformerAttention(LaneModule, nn.Module):
|
| 472 |
def __init__(
|
| 473 |
self,
|
| 474 |
+
config: LaneformerConfig,
|
| 475 |
layer_idx: int,
|
| 476 |
reduce_mode: ReduceMode = ReduceMode.PRESENT,
|
| 477 |
):
|
|
|
|
| 580 |
|
| 581 |
class LaneformerMLP(LaneModule, nn.Module):
|
| 582 |
def __init__(
|
| 583 |
+
self, config: LaneformerConfig, reduce_mode: ReduceMode = ReduceMode.PRESENT
|
| 584 |
):
|
| 585 |
super().__init__(
|
| 586 |
no_reduce_scale=math.sqrt(config.num_lanes), reduce_mode=reduce_mode
|
|
|
|
| 600 |
class LaneformerDecoderLayer(nn.Module):
|
| 601 |
def __init__(
|
| 602 |
self,
|
| 603 |
+
config: LaneformerConfig,
|
| 604 |
layer_idx: int,
|
| 605 |
attention_reduce_mode: ReduceMode,
|
| 606 |
mlp_reduce_mode: ReduceMode,
|
|
|
|
| 667 |
# Backbone & HF wrappers
|
| 668 |
# ============================================================
|
| 669 |
class LaneformerPreTrainedModel(PreTrainedModel):
|
| 670 |
+
config_class = LaneformerConfig
|
| 671 |
+
config: LaneformerConfig
|
| 672 |
base_model_prefix = "model"
|
| 673 |
supports_gradient_checkpointing = False
|
| 674 |
_no_split_modules = [
|
| 675 |
+
"LaneformerModel",
|
| 676 |
"LaneformerDecoderLayer",
|
| 677 |
"LaneformerAttention",
|
| 678 |
"LaneformerMLP",
|
|
|
|
| 681 |
# Advertise support for Transformers attention backends (vLLM / flash / sdpa routing)
|
| 682 |
_supports_attention_backend = True
|
| 683 |
_supports_sdpa = True
|
|
|
|
| 684 |
|
| 685 |
|
| 686 |
+
class LaneformerModel(LaneformerPreTrainedModel):
|
| 687 |
+
def __init__(self, config: LaneformerConfig):
|
| 688 |
super().__init__(config)
|
| 689 |
self.padding_idx = config.pad_token_id
|
| 690 |
self.config = config
|
|
|
|
| 910 |
|
| 911 |
|
| 912 |
@auto_docstring
|
| 913 |
+
class LaneformerForCausalLM(LaneformerPreTrainedModel, GenerationMixin):
|
| 914 |
_pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
|
| 915 |
|
| 916 |
+
def __init__(self, config: LaneformerConfig):
|
| 917 |
super().__init__(config)
|
| 918 |
if config.tie_word_embeddings:
|
| 919 |
+
raise ValueError("tie_word_embeddings is not supported for Laneformer")
|
| 920 |
+
self.model = LaneformerModel(config)
|
| 921 |
self.vocab_size = config.vocab_size
|
| 922 |
self.lm_head_type = config.lm_head_type
|
| 923 |
if self.lm_head_type == "replicate":
|
|
|
|
| 978 |
**kwargs: Unpack[TransformersKwargs],
|
| 979 |
) -> CausalLMOutputWithPast:
|
| 980 |
r"""
|
| 981 |
+
Example with a tiny randomly initialized Laneformer model:
|
| 982 |
|
| 983 |
```python
|
| 984 |
>>> import torch
|
| 985 |
+
>>> from torchtitan.models.laneformer.hf import (
|
| 986 |
+
... LaneformerConfig,
|
| 987 |
+
... LaneformerForCausalLM,
|
| 988 |
... )
|
| 989 |
+
>>> config = LaneformerConfig(
|
| 990 |
... hidden_size=16,
|
| 991 |
... num_hidden_layers=2,
|
| 992 |
... num_attention_heads=4,
|
|
|
|
| 995 |
... vocab_size=64,
|
| 996 |
... num_lanes=2,
|
| 997 |
... )
|
| 998 |
+
>>> model = LaneformerForCausalLM(config)
|
| 999 |
>>> input_ids = torch.tensor([[1, 2, 3]])
|
| 1000 |
>>> logits = model(input_ids=input_ids, use_cache=False).logits
|
| 1001 |
>>> logits.shape
|
tokenizer_config.json
CHANGED
|
@@ -32,12 +32,12 @@
|
|
| 32 |
"clean_up_tokenization_spaces": false,
|
| 33 |
"eos_token": "</s>",
|
| 34 |
"extra_special_tokens": {},
|
| 35 |
-
"legacy":
|
| 36 |
"model_max_length": 1000000000000000019884624838656,
|
| 37 |
"pad_token": "</s>",
|
| 38 |
"padding_side": "right",
|
| 39 |
"sp_model_kwargs": {},
|
| 40 |
-
"tokenizer_class": "
|
| 41 |
"unk_token": "<unk>",
|
| 42 |
"use_default_system_prompt": false
|
| 43 |
}
|
|
|
|
| 32 |
"clean_up_tokenization_spaces": false,
|
| 33 |
"eos_token": "</s>",
|
| 34 |
"extra_special_tokens": {},
|
| 35 |
+
"legacy": true,
|
| 36 |
"model_max_length": 1000000000000000019884624838656,
|
| 37 |
"pad_token": "</s>",
|
| 38 |
"padding_side": "right",
|
| 39 |
"sp_model_kwargs": {},
|
| 40 |
+
"tokenizer_class": "LlamaTokenizerFast",
|
| 41 |
"unk_token": "<unk>",
|
| 42 |
"use_default_system_prompt": false
|
| 43 |
}
|
torchtitan_metadata.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
-
"format": "
|
| 3 |
"version": 1,
|
| 4 |
-
"model_type": "
|
| 5 |
"torchtitan_model_args": {
|
| 6 |
"attn_mask_type": "block_causal",
|
| 7 |
"depth_init": true,
|
|
|
|
| 1 |
{
|
| 2 |
+
"format": "torchtitan_laneformer_metadata",
|
| 3 |
"version": 1,
|
| 4 |
+
"model_type": "laneformer",
|
| 5 |
"torchtitan_model_args": {
|
| 6 |
"attn_mask_type": "block_causal",
|
| 7 |
"depth_init": true,
|