mg-kog commited on
Commit
b4f40ad
·
verified ·
1 Parent(s): 027051d

Publich Laneformer 1B instruct

Browse files
LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Kog LaneformerTP Repository License Notice
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: laneformer_tp
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 2B-class decoder-only causal language model built around **Laneformer** and **Delayed Tensor Parallelism (DTP)**, a latency-oriented Transformer variant designed to overlap tensor-parallel communication with useful computation and weight streaming.
47
 
48
- The model is intended to make our Laneformer architecture available in the Hugging Face ecosystem for research, inspection, fine-tuning experiments, and compatibility testing. It is also the architecture family used in our public inference-engine preview, where single-request decoding speeds is **3,000 output tokens/s/request on 8x AMD MI300X** and **2,100 output tokens/s/request on 8x NVIDIA H200** in FP16 without speculative decoding.
49
 
50
- Those numbers are **Kog Inference Engine (KIE) benchmark results**, not expected performance from the generic Transformers reference path.
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 DTP 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
- ## Model details
66
-
67
- | Field | Value |
68
- |---|---:|
69
- | Model family | Laneformer |
70
- | HF model type | `laneformer_tp` |
71
- | Architecture class | `LaneformerTPForCausalLM` |
72
- | Task | Decoder-only causal language modeling |
73
- | Parameters | ~2.3B |
74
- | Hidden size | 3072 |
75
- | Layers | 15 |
76
- | Attention heads | 32 |
77
- | KV heads | 16 |
78
- | Intermediate size | 12288 |
79
- | Context length | 4096 tokens |
80
- | Vocabulary size | 32000 |
81
- | Tokenizer | Llama 2 tokenizer |
82
- | Number of lanes | 8 |
83
- | Broadcast delay | 2 |
84
- | LM head type | `vocab_parallel` |
85
- | Sliding window | 2048 tokens |
86
- | Sliding-window layers | 0-9 |
87
- | Full-attention layers | 10-14 |
88
- | RoPE theta | 10000 |
89
- | Tied word embeddings | false |
90
- | Expected Transformers version | `>=4.57.1` |
91
- | Published weight dtype | BFloat16 |
92
-
93
- ## Architecture overview
94
-
95
- Laneformer follows a Llama-style decoder-only architecture, but restructures tensor-parallel communication around **lanes**. In standard tensor parallelism, each attention or MLP module typically requires communication before downstream computation can proceed. In Delayed Tensor Parallelism, local outputs are communicated asynchronously and consumed several modules later, allowing communication latency to be hidden behind subsequent computation and weight streaming.
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
- ## Installation
110
 
111
- ### Nvidia
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
- ### AMD
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
- ## Usage
 
 
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
- prompts = [
168
- "Explain how a binary heap works, then write a complete min-heap implementation from scratch in Python.",
 
 
 
169
  ]
170
 
171
  print("\nPrompt:")
172
- print(prompts[0])
173
- print("\nTokenizing prompt...")
174
- inputs = tokenizer(
175
- prompts,
 
 
176
  return_tensors="pt",
177
- padding=True,
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
- ### Safer custom-code loading
202
 
203
- Because this model uses remote custom code, pin a reviewed commit hash for reproducible and safer usage:
204
 
205
- ```python
206
- commit_hash = "<reviewed-commit-hash>"
207
- model = AutoModelForCausalLM.from_pretrained(
208
- "kogai/laneformer-2b-it",
209
- trust_remote_code=True,
210
- revision=commit_hash,
211
- dtype="auto",
212
- device_map="auto",
213
- )
214
- ```
215
 
216
- ## Tokenizer
217
 
218
- This repository uses the **Llama 2 tokenizer** with a 32,000-token vocabulary. The expected special-token convention is:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
- | Token | ID |
221
- |---|---:|
222
- | `<unk>` | 0 |
223
- | `<s>` | 1 |
224
- | `</s>` | 2 |
225
 
226
- The model config uses `eos_token_id = 2` and `pad_token_id = 2`.
227
 
228
- ## Training data and procedure
 
 
229
 
230
- This checkpoint was trained with a staged language-modeling recipe designed to first learn broad language/modeling capabilities and then continue training on a code- and reasoning-focused mixture. The TorchTitan training configs use sequence length 4096 and global batch size 1536, or 6,291,456 tokens per optimizer step.
231
 
232
- ### Training stages
233
 
234
- | Stage | Focus | Framework | Tokens | Steps | Approx. tokens / step | Notes |
235
- |---|---|---|---:|---:|---:|---|
236
- | Pre-training | General language-model pre-training | TorchTitan | ~4T | 620,000 | ~6.29M | NVIDIA Nemotron pre-training datasets; final checkpoint selected. |
237
- | Mid-training | Code- and reasoning-focused continuation training | TorchTitan | ~2T | 310,000 | ~6.29M | NVIDIA Nemotron pre-training datasets; initialized from the Pre-training checkpoint. |
238
- | Post-training | SFT, instruction tuning | Hugging Face Transformers | ~210M | 200 | ~1.05M | Custom data mixture; Initialized from the mid-training checkpoint. |
239
 
240
- ### Data sources
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
- ### Training infrastructure
245
-
246
- | Field | Value |
247
- |---|---|
248
- | Pre-training framework | TorchTitan |
249
- | Post-training framework | Hugging Face Transformers |
250
- | Training hardware | 24 nodes × 8 NVIDIA H100 GPUs = 192 H100 GPUs |
251
- | Training clusters | Scaleway cluster; ADASTRA cluster |
252
- | Cloud/provider/region | France |
253
- | Training time | ~21 days |
254
- | Precision | FP32/BF16 mixed precision |
255
- | Parallelism | Data-parallel |
256
- | Optimizer | AdamW |
257
- | Learning-rate schedule | WSD |
258
- | Sequence length during training | 4096 |
259
- | Checkpoint selection | final step |
260
-
261
- ## Inference and performance
 
 
 
 
 
 
 
 
262
 
263
  Kog Inference Engine running the Laneformer 2B model public-preview numbers:
264
 
265
- | Setting | Reported speed | Notes |
266
- |---|---:|---|
267
- | 8x AMD MI300X | 3,000 output tokens/s/request | FP16, batch size 1, no speculative decoding |
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 with `lm-evaluation-harness` 0.4.12 against a local Kog serving endpoint for `Kog Laneformer 2B` @ batch size 1 in FP16. These numbers evaluate the served preview model.
275
-
276
- All values are percentages.
277
-
278
- | Benchmark | Metric | Value | Samples | Setting |
279
- |---|---:|---:|---:|---|
280
- | HumanEval | pass@1 | 53.05 | 164 | 0-shot generation; greedy decoding; `max_gen_toks=1024` |
281
- | HumanEval+ | pass@1 | 50.00 | 164 | Same as HumanEval pass@1, using `evalplus/humanevalplus` |
282
- | HumanEval | pass@16 | 77.44 | 164 | 16 sampled completions; `temperature=0.8`; `top_p=1.0`; `max_gen_toks=1024` |
283
- | IFEval | prompt-level strict accuracy | 12.57 | 541 | 0-shot chat generation; greedy decoding; `temperature=0`; `max_gen_toks=1280` |
284
- | IFEval | instruction-level strict accuracy | 23.74 | 541 | Same IFEval run |
285
- | ARC-Challenge | normalized accuracy | 31.06 | 1,172 | 0-shot multiple-choice logprobs |
286
- | ARC-Easy | normalized accuracy | 47.90 | 2,376 | 0-shot multiple-choice logprobs |
287
- | MMLU-Pro | exact match, custom extract | 11.77 | 12,032 | 5-shot chain-of-thought generation; greedy decoding; |
288
- | GPQA Diamond | normalized accuracy | 25.25 | 198 | 0-shot multiple-choice logprobs |
289
- | GPQA Main | normalized accuracy | 25.22 | 448 | 0-shot multiple-choice logprobs |
290
- | GPQA Extended | normalized accuracy | 21.98 | 546 | 0-shot multiple-choice logprobs |
291
-
292
- Long-context checks were also run with RULER-style synthetic tasks at 2,048 and 4,096 tokens using 0-shot greedy chat generation (`temperature=0`, remote tokenizer, `max_length=4096`). Values below are string-match scores.
293
-
294
- | Task | 2,048 tokens | 4,096 tokens | Effective samples |
295
- |---|---:|---:|---:|
296
- | NIAH single 1 | 100.00 | 100.00 | 500 |
297
- | NIAH single 2 | 100.00 | 100.00 | 500 |
298
- | NIAH single 3 | 99.80 | 91.60 | 500 |
299
- | NIAH multikey 1 | 99.20 | 83.40 | 500 |
300
- | NIAH multikey 2 | 97.80 | 60.00 | 500 |
301
- | NIAH multikey 3 | 91.80 | 91.20 | 500 |
302
- | NIAH multiquery | 95.40 | 69.70 | 500 |
303
- | NIAH multivalue | 94.60 | 82.20 | 500 |
304
- | RULER variable tracking | 77.92 | 3.92 | 500 |
305
- | RULER common words extraction | 24.72 | 78.14 | 500 |
306
- | RULER frequent words extraction | 78.80 | 64.73 | 500 |
307
-
308
- TODO (I'll add all benchmark and remove this sentence): HellaSwag, standard MMLU, and GSM8K are not reported for this release.
309
-
310
- ## Intended use
 
 
 
 
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
- ## Out-of-scope use
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. Do not present generated outputs as factual without independent verification. Do not use the model as the sole decision-maker in high-stakes workflows.
325
 
326
- ## Limitations and risks
 
 
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 only.
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
- ## License
338
 
339
  This repository is **multi-license**.
340
 
341
- ### Kog-owned materials: Apache License 2.0
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
- ### Tokenizer materials: Llama 2 Community License
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
- ## Citation
366
 
367
- If you use this model or architecture, please cite the model repository and the Kog technical blog posts:
368
 
369
  ```bibtex
370
- @misc{kog_laneformer_tp_2b_2026,
371
- title = {Kog Laneformer 2B},
372
- author = {Kog AI},
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
- ## Contact
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 LaneformerTPConfig
4
- from .modeling_laneformer import LaneformerTPForCausalLM, LaneformerTPModel
5
 
6
- LaneformerTPConfig.register_for_auto_class()
7
- LaneformerTPModel.register_for_auto_class("AutoModel")
8
- LaneformerTPForCausalLM.register_for_auto_class("AutoModelForCausalLM")
9
- AutoConfig.register("laneformer_tp", LaneformerTPConfig)
10
 
11
- __all__ = ["LaneformerTPConfig", "LaneformerTPModel", "LaneformerTPForCausalLM"]
 
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": "laneformer_tp",
3
  "architectures": [
4
- "LaneformerTPForCausalLM"
5
  ],
6
  "auto_map": {
7
- "AutoConfig": "configuration_laneformer.LaneformerTPConfig",
8
- "AutoModel": "modeling_laneformer.LaneformerTPModel",
9
- "AutoModelForCausalLM": "modeling_laneformer.LaneformerTPForCausalLM"
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": 8192,
17
- "max_seq_len": 8192,
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": "flex_attention",
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 LaneformerTPConfig(PretrainedConfig):
125
- model_type = "laneformer_tp"
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 LaneformerTP")
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
- - LaneformerTPPreTrainedModel
6
- - LaneformerTPModel (backbone)
7
- - LaneformerTPForCausalLM (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,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 LaneformerTPConfig
39
 
40
 
41
  # ============================================================
@@ -50,7 +50,7 @@ class RoPEScalingArgs:
50
 
51
 
52
  def _rope_scaling_from_config(
53
- config: LaneformerTPConfig,
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: LaneformerTPConfig):
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: LaneformerTPConfig,
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: LaneformerTPConfig,
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: LaneformerTPConfig,
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: LaneformerTPConfig,
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: LaneformerTPConfig, reduce_mode: ReduceMode = ReduceMode.PRESENT
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: LaneformerTPConfig,
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 = LaneformerTPConfig
671
- config: LaneformerTPConfig
672
  base_model_prefix = "model"
673
  supports_gradient_checkpointing = False
674
  _no_split_modules = [
675
- "LaneformerTPModel",
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 LaneformerTPModel(LaneformerPreTrainedModel):
688
- def __init__(self, config: LaneformerTPConfig):
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 LaneformerTPForCausalLM(LaneformerPreTrainedModel, GenerationMixin):
915
  _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
916
 
917
- def __init__(self, config: LaneformerTPConfig):
918
  super().__init__(config)
919
  if config.tie_word_embeddings:
920
- raise ValueError("tie_word_embeddings is not supported for LaneformerTP")
921
- self.model = LaneformerTPModel(config)
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 LaneformerTP model:
983
 
984
  ```python
985
  >>> import torch
986
- >>> from torchtitan.models.laneformer_tp.hf import (
987
- ... LaneformerTPConfig,
988
- ... LaneformerTPForCausalLM,
989
  ... )
990
- >>> config = LaneformerTPConfig(
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 = LaneformerTPForCausalLM(config)
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": false,
36
  "model_max_length": 1000000000000000019884624838656,
37
  "pad_token": "</s>",
38
  "padding_side": "right",
39
  "sp_model_kwargs": {},
40
- "tokenizer_class": "LlamaTokenizer",
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": "torchtitan_laneformer_tp_metadata",
3
  "version": 1,
4
- "model_type": "laneformer_tp",
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,