Model reference · open weights

huginn-0125

LLMs tomg-group-umd Text gen 1 build Open weights 29k dl/mo

huginn-0125 is an open-weight language model from tomg-group-umd. huginn-0125 (FP32) weighs 7.8 GB; the smallest configuration that runs it is RTX 3060 12 GB.

For self-hosting, compare this build's requirements below with the GPU you plan to rent.

  • Huginn-0125 is a 3.9B parameter latent recurrent-depth model developed by tomg-group-umd for text generation tasks.
  • It supports English and is released under the Apache-2.0 license.
  • The model allows users to adjust the number of recurrent steps at test time to vary the amount of compute used for reasoning.

Summary of the tomg-group-umd/huginn-0125 model card, 2026-10-01

What it is

Released bytomg-group-umd
Released2025-01-08
Parameters3.9B
VRAM7.8 GB for the weights

What it runs on

Memory and cards for huginn-0125 (FP32)

7.8 GBweights, file size
169 MBcache per 1K tokens
730 MBruntime overhead, at least
CardRequests at onceContext maxMemory
8K each32K each
RTX 3060 12 GB217K11.6 GB
RTX 4060 Ti 16 GB4139K15.4 GB
RTX 3090 24 GB10285K23.4 GB
RTX 4090 24 GB10285K23.4 GB
RTX 5090 32 GB164128K31.0 GB
L40S 48 GB256128K44.0 GB
A100 80 GB5012128K78.2 GB
H100 80 GB4711128K78.1 GB
RTX PRO 6000 Blackwell 96 GB5914128K93.8 GB
DGX Spark (GB10) 128 GB unified6817128K107 GB
H200 141 GB9022128K138 GB
B200 180 GB11729128K176 GB
Memory needed at each load
Requests at once8K tokens each32K tokens each
19.9 GB14.1 GB
515.5 GB36.2 GB
819.6 GB52.8 GB
1630.7 GB97.1 GB
3252.8 GB186 GB
6497.1 GB363 GB

One card, with vLLM's small-card settings.

From the model card

What tomg-group-umd says about huginn-0125

Read the model card

This is Huginn, version 01/25, a latent recurrent-depth model with 3.5B parameters, trained for 800B tokens on AMD MI250X machines. This is a proof-of-concept model, but surprisingly capable in reasoning and code given its training budget and size. All details on this model can be found in the tech report: "Scaling up Test-Time Compute with Latent Reasoning: A Recurrent Depth Approach." (https://www.arxiv.org/abs/2502.05171) For more information, see the paper page: https://huggingface.co/papers/2502.05171.

8 intermediate checkpoints of the model can be found in its collection. Additional intermediate checkpoints are available upon request while we find a place to host all ~350 of them. The data used to train this model is publicly available (entirely on Hugging Face), and scripts provided with the pretraining code at https://github.com/seal-rg/recurrent-pretraining can be used to repeat our preprocessing and our entire training run.

Table of Contents

  1. How to Use
  2. Advanced Usage
  3. Model Summary
  4. Limitations
  5. Technical Details
  6. License
  7. Citation

Downloading and Using the Model

Load the model like this:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, GenerationConfig

model = AutoModelForCausalLM.from_pretrained("tomg-group-umd/huginn-0125", torch_dtype=torch.bfloat16, trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained("tomg-group-umd/huginn-0125")

Modifying the Model's Depth at Test Time:

By providing the argument num_steps, the model will execute a forward pass with that amount of compute:

input_ids = tokenizer.encode("The capital of Westphalia is", return_tensors="pt", add_special_tokens=True).to(device)
model.eval()
model.to(device)

model(input_ids, num_steps=32)

The model has about 1.5B parameters in its non-recurrent layers (prelude+coda), 0.5B parameters in the embedding, and 1.5B recurrent parameters, so, as a guideline, the number of materialized parameters is num_steps * 1.5B + 2B. Playing with this parameter is what makes this model interesting, and different from fixed-depth transformers! The model is trained to accept an arbitrary number of steps. However, using fewer than 4 steps will result in very coarse answers. If given enough context to reason about, benchmarks show the model improving up to around num_steps=64. Beyond that, more steps generally do not hurt, but we see no further improvements.

Note: Due to an upload issue the model is currently stored on HF with 2 copies of the tied embedding, instead of just one. This will be fixed in a future release.

Inference

The model was trained with bfloat16-mixed precision, so we recommend using bfloat16 to run inference (or AMP bfloat16-mixed precision, if you really want). All benchmarks were evaluated in pure bfloat16.

Sampling

The model can be used like a normal HF model to generate text with KV-caching working as expected. You can provide num_steps directly to the generate call, for example:

model.eval()
config = GenerationConfig(max_length=256, stop_strings=["", ""],
                          use_cache=True,
                          do_sample=False, temperature=None, top_k=None, top_p=None, min_p=None,
                          return_dict_in_generate=True,
                          eos_token_id=65505,bos_token_id=65504,pad_token_id=65509)

input_ids = tokenizer.encode("The capital of Westphalia is", return_tensors="pt", add_special_tokens=True).to(device)
outputs = model.generate(input_ids, config, tokenizer=tokenizer, num_steps=16)

Note: num_steps and other model arguments CANNOT be included in the GenerationConfig, they will shadow model args at runtime.

Chat Templating

The model was not finetuned or post-trained, but due to inclusion of instruction data during pretraining, natively understand its chat template. You can chat with the model like so

messages = []
messages.append({"role": "system", "content" : "You are a helpful assistant."})
messages.append({"role": "user", "content" : "What do you think of Goethe's Faust?"})
chat_input = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
print(chat_input)
input_ids = tokenizer.encode(chat_input, return_tensors="pt", add_special_tokens=False).to(device)

model.generate(input_ids, config, num_steps=64, tokenizer=tokenizer)

KV-cache Details

The model requires its own KV-cache implementation HuginnDynamicCache, otherwise the KV-caches of later calls to the recurrent block will overwrite the earlier ones. The current implementation will always try to inject this Cache implementation, but that may break with huggingface updates. If you do not use generate, but implement your own generation, use a pattern like this:

# first step:
past_key_values = None
outputs = model(input_ids=input_ids, use_cache=True, past_key_values=past_key_values)
past_key_values = outputs.past_key_values # Should be an instance of HuginnDynamicCache
# next step
outputs = model(input_ids=input_ids, use_cache=True, past_key_values=past_key_values)

Advanced Features

Per-Token Adaptive Compute

When generating, you can use a variable amount of compute per-token. The model is not trained for this, so this is a proof-of-concept, that it can do this task zero-shot. You can pick between a few sane stopping rules, entropy-diff, latent-diff,kl and argmax-stability, via criterion=.... The exit threshold can be modified via exit_threshold=5e-4. We suggest using kl for interesting exits and argmax-stability for conservative exits. Note that using these variables overrides the default generation function. Not all arguments that are valid for the normal generate call are valid here. To make this more explicit, you can also directly call `generate_with_adaptive

Quoted from the model card on Hugging Face. The full card is behind the Hugging Face link above.

© 2026 AxForge · EU-hosted AI infrastructure Pricing Docs Trust Privacy Terms