HRM-Text-1B Code and Tool-Use SFT

This repository is a Transformers BF16 conversion of pzarzycki/hrm-text-1b-code-tools-sft, a full-parameter Stage A fine-tune of sapientinc/HRM-Text-1B. It also contains canonical BF16 and directly derived Q8_0 GGUF files.

The source checkpoint is a research pilot trained for code generation and a fixed tool-transcript protocol. It has not undergone downstream benchmark or production-agent evaluation.

Model details

Field Value
Architecture HRM-Text PrefixLM
Parameters 1,182,795,264
Stored dtype BF16
Hidden size 1,536
H/L stack depth 16 layers each
Recurrence H_cycles=2, L_cycles=3
Attention 12 heads, head dimension 128, gated MHA
Intermediate size 4,096, SwiGLU
Context length 4,096 tokens
Vocabulary 65,536
Position encoding RoPE, theta 10,000
Normalization Parameterless pre-RMSNorm
Training stage Stage A pilot, seed 17
Training budget 10,000,147 response tokens
Primary language English

Stage B was not trained or published as part of the source revision used here.

Files

File Format Size SHA256
model.safetensors Transformers BF16 2,365,606,568 bytes 2bc954894ab677dcdc66331863cf12aa4da8aa719fa56538a816632a3935546b
gguf/HRM-Text-1B-Code-Tools-SFT-BF16.gguf GGUF BF16 2,367,996,448 bytes 4c59b7f0187315ba942088c07e7aeee38339bbfdcc1da05f4e83d3efd3c22cf7
gguf/HRM-Text-1B-Code-Tools-SFT-Q8_0.gguf GGUF Q8_0 1,259,127,360 bytes b0faf21c398ca4935d458d60decf6d3e60e9bc5d8dbfb1bf92d370b37bc9252e
gguf/runtime/llama.cpp-hrm_text.patch llama.cpp runtime patch - See compatibility section

BF16 is the canonical storage format. Q8_0 was quantized directly from the BF16 GGUF. No F16 derivative is provided because converting BF16 to F16 would change 17,119 finite stored values and underflow 87 values to zero.

Requirements

Use transformers>=5.9.0, which includes native hrm_text model support. The conversion and validation environment used Transformers 5.16.1 and PyTorch 2.13.0.

pip install --upgrade "transformers>=5.9.0" torch

Hosted inference is disabled in the model-card metadata because generic text generation endpoints do not provide the required PrefixLM token_type_ids.

Transformers usage

The included Jinja template must be applied. It serializes the learned direct condition and the SFT transcript markup; this is not a Qwen/ChatML prompt despite using a Qwen-compatible tokenizer.

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "YOUR_NAMESPACE/HRM-Text-1B-Code-Tools-SFT"
device = torch.device(
    "cuda" if torch.cuda.is_available()
    else "mps" if torch.backends.mps.is_available()
    else "cpu"
)

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    dtype=torch.bfloat16,
).to(device).eval()

messages = [
    {
        "role": "user",
        "content": "Write a Python function that returns the larger of two integers.",
    }
]
inputs = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_tensors="pt",
    return_dict=True,
).to(device)

# HRM-Text was trained with a bidirectional prompt prefix.
inputs["token_type_ids"] = torch.ones_like(inputs["input_ids"])

with torch.inference_mode():
    output_ids = model.generate(
        **inputs,
        max_new_tokens=256,
        do_sample=False,
    )

new_ids = output_ids[0, inputs["input_ids"].shape[1]:]
print(tokenizer.decode(new_ids, skip_special_tokens=False))

The rendered prompt starts with the following exact envelope:

<|im_start|><|object_ref_start|><user>
Write a Python function that returns the larger of two integers.
</user>
<assistant>
<|im_end|>

Do not omit token_type_ids when using Transformers. A value of 1 marks a prompt position as part of the bidirectional prefix block. Omitting it falls back to pure-causal attention and does not match the training-time objective.

Tool schemas

Pass OpenAI-style function schemas through the tools argument. The template places them inside the learned <tools>...</tools> transcript markup.

tools = [
    {
        "type": "function",
        "function": {
            "name": "read_file",
            "description": "Read a UTF-8 file relative to the task root.",
            "parameters": {
                "type": "object",
                "properties": {"path": {"type": "string"}},
                "required": ["path"],
                "additionalProperties": False,
            },
        },
    }
]

prompt = tokenizer.apply_chat_template(
    [{"role": "user", "content": "Read README.md and summarize it."}],
    tools=tools,
    tokenize=False,
    add_generation_prompt=True,
)

<user>, <assistant>, <tools>, <tool_call>, and <tool_result> are ordinary learned text markup, not pretrained HRM control tokens. The model does not execute tools, validate arguments, or sandbox generated code. A system message is intentionally serialized with the same <user> markup; there is no separately trained system role.

GGUF compatibility

The GGUF files use general.architecture = hrm_text and embed the exact Jinja template under tokenizer.chat_template. Standard unpatched llama.cpp, Ollama, LM Studio, and llama-cpp-python builds do not support this custom runtime graph at the time of this release.

Apply the included patch to this exact llama.cpp commit:

6a257d44633d4a752183ed778b88d2924d0a6b9d
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
git checkout 6a257d44633d4a752183ed778b88d2924d0a6b9d
git apply /path/to/model/gguf/runtime/llama.cpp-hrm_text.patch
cmake -B build -DGGML_METAL=ON -DGGML_NATIVE=OFF -DLLAMA_BUILD_UI=OFF
cmake --build build --config Release --target llama-cli llama-server llama-quantize -j

Ninja is optional. The documented CMake flow works with the default Unix Makefiles generator, and Metal support is independent of the generator.

Start the server with Jinja explicitly enabled. PrefixLM prefill must process the complete prompt in one physical batch, so set --batch-size and --ubatch-size to at least the maximum prompt length you intend to use. The example below supports prompts up to 512 tokens. Use -ngl all for Metal or -ngl 0 for CPU-only inference.

./build/bin/llama-server \
  -m /path/to/model/gguf/HRM-Text-1B-Code-Tools-SFT-Q8_0.gguf \
  --alias HRM-Text-1B-Code-Tools-SFT \
    --jinja --ctx-size 512 --batch-size 512 --ubatch-size 512 \
    --cache-ram 0 --parallel 1 \
    -ngl all --host 127.0.0.1 --port 8080

Requests to the OpenAI-compatible chat endpoint apply the embedded template:

curl http://127.0.0.1:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "HRM-Text-1B-Code-Tools-SFT",
    "messages": [{"role": "user", "content": "Write a Python max function."}],
    "temperature": 0,
        "max_tokens": 128,
        "cache_prompt": false
  }'

The patch maps hrm_text.prefix_lm=true to llama.cpp's non-causal attention mask. The complete initial prompt is therefore one bidirectional prefix block. Autoregressive token-by-token decoding remains causal in effect because the KV cache contains no future generated positions.

This is deliberately narrower than arbitrary Transformers token_type_ids. Do not split one prefix across multiple physical batches, reuse a KV cache from a shorter prompt, or enable speculative multi-token decoding. Prompt-cache reuse is disabled in the command and request above. For the full 4,096-token context, set --ctx-size, --batch-size, and --ubatch-size to 4096 if the available memory permits it.

Conversion validation

Check Result
Source Keras H5 to Transformers BF16 values 1,182,795,264 checked, 0 bit mismatches
Tensor mapping 259 Keras tensors mapped to 131 fused Safetensors entries
Keras vs Transformers FP32, pure causal Maximum absolute logit difference 7.2718e-06
Keras vs Transformers FP32, direct PrefixLM Maximum absolute logit difference 2.0981e-05
Author conversion tolerance Passed at atol=2e-4, rtol=2e-4
BF16 MPS top-1 All tested positions matched
BF16 MPS final-position top-10 10/10 overlap
BF16 MPS two-step greedy generation Matched for causal and PrefixLM cases
Chat template Plain and tool-schema cases passed
GGUF structure 259 tensors and embedded Jinja verified for BF16 and Q8_0
BF16 GGUF, Metal 129/129 layers on MTL0; both two-token continuations matched Transformers PrefixLM baseline
BF16 GGUF, CPU 0/129 layers offloaded; both two-token continuations matched
Q8_0 GGUF, Metal 129/129 layers on MTL0; both two-token continuations matched
llama.cpp PrefixLM mask prefix_lm=true, causal_attn=0, complete-prompt prefill, prompt cache disabled
llama.cpp Jinja /apply-template strings and /tokenize IDs matched for plain and tool-schema prompts
llama.cpp token ranking Top-1 matched at all 12 checked steps; top-10 overlap was 9/10 or 10/10
OpenAI-compatible chat route /v1/chat/completions passed with embedded Jinja enabled for all three runtime targets

BF16 logits are not bit-identical across Keras and Transformers because their RMSNorm, softmax, and backend arithmetic paths differ. Stored weights are bit-identical after the audited tensor mapping, FP32 outputs pass the source author's tolerance, and the tested BF16 token rankings and greedy outputs match.

The llama.cpp comparisons use the same rendered token IDs and PrefixLM mask on both sides: every initial prompt token is bidirectional and generated tokens are causal. The validated two-step continuations were [26763, 2336] for the plain prompt and [58, 19975] for the tool-schema prompt on BF16 CPU, BF16 Metal, and Q8_0 Metal.

Training provenance

Item Value
SFT source repository pzarzycki/hrm-text-1b-code-tools-sft
SFT source revision ab083a772a29d4999251a437fe4e8b6007f828c3
Source Keras H5 SHA256 8ddb10cea110edff99380b360ec569e5dbde0d4a233d1c058b0e292700a42b84
Base model sapientinc/HRM-Text-1B
Training dataset pzarzycki/hrm-text-code-tools-sft, canonical v2 Stage A
Underlying data source nvidia/OpenCodeInstruct revision 8f3ba5bafe4d6e8db46082cf7ae6741bc370604d
KerasHub reference implementation pzarzycki/keras-hub revision 8e9207acfae1833c25ba6813932b4234b6b84bf9

The Stage A selection contains 38,248 rows from the sealed training split. Training used full-parameter BF16 optimization with a 4,096-token context cap. See the source model card for the full optimizer setup and telemetry.

Intended use and limitations

This checkpoint is intended for research on HRM-Text code adaptation, tool-call transcript generation, conversion fidelity, and local inference.

  • No downstream coding or agent benchmark has been reported for this pilot.
  • Training loss is not evidence of production coding-agent performance.
  • Generated code and tool calls may be incorrect, unsafe, or fabricated.
  • Tool execution, argument validation, permissions, and sandboxing must be implemented by the host application.
  • The model is predominantly English and is limited to 4,096 tokens.
  • Evaluate task quality and safety independently before deployment.

License and citation

The model is released under the Apache License 2.0. The Stage A dataset traces to CC-BY-4.0 data; consult the linked dataset card for its attribution and usage terms.

Please cite the base HRM-Text work:

@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}
}
Downloads last month
39
Safetensors
Model size
1B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for vonjack/hrm-text-code-tools-sft

Finetuned
(13)
this model

Dataset used to train vonjack/hrm-text-code-tools-sft

Paper for vonjack/hrm-text-code-tools-sft