Views
No views yet


H_cycles × (L_cycles + 1) steps, with additive state injection (z_L + z_H). This gives effectively unbounded compute depth at bounded parameter count.direct condition with 2–8 few-shot in-context examples. direct + few-shot is the strongest zero-extra-training setup we have measured; pure zero-shot is noticeably weaker.synth,cot. This is one composite prefix, not two alternatives — at tokenization time the comma-separated tags are mapped to their prefix tokens and concatenated, in order, into a single prefix block. So synth,cot produces the two-token prefix <|quad_end|><|object_ref_end|> (synth first, then cot), wrapped in the usual <|im_start|> … <|im_end|> envelope. Under this composite the model exhibits some chain-of-thought / instruct-like behavior — enough to answer many zero-shot math and reasoning prompts in a step-by-step style — but quality is uneven and below an instruction-tuned model of comparable size. Treat this "instruct" ability as a side effect of the pre-training mix, not a guaranteed capability.direct → <|object_ref_start|> — direct answer, no CoTcot → <|object_ref_end|> — chain-of-thoughtnoisy → <|quad_start|> — noisy / web-crawl stylesynth → <|quad_end|> — synthetic / curated styletransformers >= 5.9.0, which ships native support for the hrm_text model class:pip install --upgrade "transformers>=5.9.0"| Field | Value |
|---|---|
| Parameters | ~1 B |
| Hidden size | 1536 |
| Layers (per H / L stack) | 16 |
| Attention heads | 12 (MHA, head_dim 128) |
| H_cycles × L_cycles | 2 × 3 |
| Max sequence length | 4096 |
| Vocabulary | 65,536 |
| Embedding | Scaled (lecun_normal) |
| Position encoding | RoPE (theta 10000) |
| Activation | SwiGLU |
| Normalization | Parameterless Pre-RMSNorm |
| Attention | Gated (sigmoid output gate) |
| Training unique tokens | 40 B |
| Optimizer | AdamATan2 (beta 0.9 / 0.95, wd 0.1, EMA 0.9999) |
| LR | 2.2e-4 (warmup 2000 steps) |
| Global batch | 196,608 tokens |
| dtype | bfloat16 |
1from transformers import AutoModelForCausalLM, AutoTokenizer
2import torch
3
4model_id = "sapientinc/HRM-Text-1B"
5tokenizer = AutoTokenizer.from_pretrained(model_id)
6model = AutoModelForCausalLM.from_pretrained(
7 model_id,
8 dtype=torch.bfloat16,
9).cuda().eval()
10
11# synth,cot composite — reasoning / CoT style (see Disclaimer for other modes)
12condition = "<|quad_end|><|object_ref_end|>"
13prompt = f"<|im_start|>{condition}Explain why the sky is blue.<|im_end|>"
14
15inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
16# Mark the prompt as a single bidirectional prefix block — see "PrefixLM mask" below.
17inputs["token_type_ids"] = torch.ones_like(inputs["input_ids"])
18
19with torch.no_grad():
20 out = model.generate(**inputs, max_new_tokens=256, do_sample=False)
21print(tokenizer.decode(out[0], skip_special_tokens=False))token_type_idstoken_type_ids:token_type_ids[i] == 1 → position i is part of the prefix block (bidirectional within the block).token_type_ids, attention falls back to pure causal, which does not match the pre-training distribution and will give noticeably worse logits. The simplest correct call passes token_type_ids = torch.ones_like(input_ids), marking the entire input prompt as one bidirectional prefix block — exactly how training-time prefill ran.z_H = embed(input_ids) * embedding_scale
z_L = z_L_init.expand_as(z_H)
for _ in range(H_cycles):
for _ in range(L_cycles):
z_L = L_module(z_L + z_H)
z_H = H_module(z_H + z_L)
return z_H@misc{wang2026hrmtextefficientpretrainingscaling,
title={HRM-Text: Efficient Pretraining Beyond Scaling},
author={Guan Wang and Changling Liu and Chenyu Wang and Cai Zhou and Yuhao Sun and Yifei Wu and Shuai Zhen and Luca Scimeca and Yasin Abbasi Yadkori},
year={2026},
eprint={2605.20613},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2605.20613},
}