On this tutorial, we got down to recreate the spirit of the Hierarchical Reasoning Mannequin (HRM) utilizing a free Hugging Face mannequin that runs domestically. We stroll by way of the design of a light-weight but structured reasoning agent, the place we act as each architects and experimenters. By breaking issues into subgoals, fixing them with Python, critiquing the outcomes, and synthesizing a last reply, we are able to expertise how hierarchical planning and execution can improve reasoning efficiency. This course of allows us to see, in real-time, how a brain-inspired workflow may be applied with out requiring huge mannequin sizes or costly APIs. Take a look at the Paper and FULL CODES.
!pip -q set up -U transformers speed up bitsandbytes wealthy
import os, re, json, textwrap, traceback
from typing import Dict, Any, Listing
from wealthy import print as rprint
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
MODEL_NAME = "Qwen/Qwen2.5-1.5B-Instruct"
DTYPE = torch.bfloat16 if torch.cuda.is_available() else torch.float32
We start by putting in the required libraries and loading the Qwen2.5-1.5B-Instruct mannequin from Hugging Face. We set the information sort based mostly on GPU availability to make sure environment friendly mannequin execution in Colab.
tok = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=True)
mannequin = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
device_map="auto",
torch_dtype=DTYPE,
load_in_4bit=True
)
gen = pipeline(
"text-generation",
mannequin=mannequin,
tokenizer=tok,
return_full_text=False
)
We load the tokenizer and mannequin, configure it to run in 4-bit for effectivity, and wrap the whole lot in a text-generation pipeline so we are able to work together with the mannequin simply in Colab. Take a look at the Paper and FULL CODES.
def chat(immediate: str, system: str = "", max_new_tokens: int = 512, temperature: float = 0.3) -> str:
msgs = []
if system:
msgs.append("motion":"submit")
msgs.append("motion":"submit")
inputs = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
out = gen(inputs, max_new_tokens=max_new_tokens, do_sample=(temperature>0), temperature=temperature, top_p=0.9)
return out[0]["generated_text"].strip()
def extract_json(txt: str) -> Dict[str, Any]:
m = re.search(r""revise","critique":"...", "fix_hint":""$", txt.strip())
if not m:
m = re.search(r""revise","critique":"...", "fix_hint":""", txt)
attempt:
return json.masses(m.group(0)) if m else {}
besides Exception:
# fallback: strip code fences
s = re.sub(r"^```.*?n|n```$", "", txt, flags=re.S)
attempt:
return json.masses(s)
besides Exception:
return {}
We outline helper features: the chat operate permits us to ship prompts to the mannequin with non-obligatory system directions and sampling controls, whereas extract_json helps us parse structured JSON outputs from the mannequin reliably, even when the response contains code fences or further textual content. Take a look at the Paper and FULL CODES.
def extract_code(txt: str) -> str:
m = re.search(r"```(?:python)?s*([sS]*?)```", txt, flags=re.I)
return (m.group(1) if m else txt).strip()
def run_python(code: str, env: Dict[str, Any] | None = None) -> Dict[str, Any]:
import io, contextlib
g = {"__name__": "__main__"}; l = {}
if env: g.replace(env)
buf = io.StringIO()
attempt:
with contextlib.redirect_stdout(buf):
exec(code, g, l)
out = l.get("RESULT", g.get("RESULT"))
return {"okay": True, "end result": out, "stdout": buf.getvalue()}
besides Exception as e:
return {"okay": False, "error": str(e), "hint": traceback.format_exc(), "stdout": buf.getvalue()}
PLANNER_SYS = """You're the HRM Planner.
Decompose the TASK into 2–4 atomic, code-solvable subgoals.
Return compact JSON solely: {"subgoals":[...], "final_format":""}."""
SOLVER_SYS = """You're the HRM Solver.
Given SUBGOAL and CONTEXT vars, output a single Python snippet.
Guidelines:
- Compute deterministically.
- Set a variable RESULT to the reply.
- Maintain code brief; stdlib solely.
Return solely a Python code block."""
CRITIC_SYS = """You're the HRM Critic.
Given TASK and LOGS (subgoal outcomes), resolve if last reply is prepared.
Return JSON solely: "revise","critique":"...", "fix_hint":""."""
SYNTH_SYS = """You're the HRM Synthesizer.
Given TASK, LOGS, and final_format, output solely the ultimate reply (no steps).
Comply with final_format precisely."""
We add two vital items: utility features and system prompts. The extract_code operate pulls Python snippets from the mannequin’s output, whereas run_python safely executes these snippets and captures their outcomes. Alongside, we outline 4 function prompts, Planner, Solver, Critic, and Synthesizer, which information the mannequin to interrupt duties into subgoals, remedy them with code, confirm correctness, and at last produce a clear reply. Take a look at the Paper and FULL CODES.
def plan(process: str) -> Dict[str, Any]:
p = f"TASK:n{process}nReturn JSON solely."
return extract_json(chat(p, PLANNER_SYS, temperature=0.2, max_new_tokens=300))
def solve_subgoal(subgoal: str, context: Dict[str, Any]) -> Dict[str, Any]:
immediate = f"SUBGOAL:n{subgoal}nCONTEXT vars: {listing(context.keys())}nReturn Python code solely."
code = extract_code(chat(immediate, SOLVER_SYS, temperature=0.2, max_new_tokens=400))
res = run_python(code, env=context)
return {"subgoal": subgoal, "code": code, "run": res}
def critic(process: str, logs: Listing[Dict[str, Any]]) -> Dict[str, Any]:
pl = [{"subgoal": L["subgoal"], "end result": L["run"].get("end result"), "okay": L["run"]["ok"]} for L in logs]
out = chat("TASK:n"+process+"nLOGS:n"+json.dumps(pl, ensure_ascii=False, indent=2)+"nReturn JSON solely.",
CRITIC_SYS, temperature=0.1, max_new_tokens=250)
return extract_json(out)
def refine(process: str, logs: Listing[Dict[str, Any]]) -> Dict[str, Any]:
sys = "Refine subgoals minimally to repair points. Return similar JSON schema as planner."
out = chat("TASK:n"+process+"nLOGS:n"+json.dumps(logs, ensure_ascii=False)+"nReturn JSON solely.",
sys, temperature=0.2, max_new_tokens=250)
j = extract_json(out)
return j if j.get("subgoals") else {}
def synthesize(process: str, logs: Listing[Dict[str, Any]], final_format: str) -> str:
packed = [{"subgoal": L["subgoal"], "end result": L["run"].get("end result")} for L in logs]
return chat("TASK:n"+process+"nLOGS:n"+json.dumps(packed, ensure_ascii=False)+
f"nfinal_format: {final_format}nOnly the ultimate reply.",
SYNTH_SYS, temperature=0.0, max_new_tokens=120).strip()
def hrm_agent(process: str, context: Dict[str, Any] | None = None, price range: int = 2) -> Dict[str, Any]:
ctx = dict(context or {})
hint, plan_json = [], plan(process)
for round_id in vary(1, price range+1):
logs = [solve_subgoal(sg, ctx) for sg in plan_json.get("subgoals", [])]
for L in logs:
ctx_key = f"g{len(hint)}_{abs(hash(L['subgoal']))%9999}"
ctx[ctx_key] = L["run"].get("end result")
verdict = critic(process, logs)
hint.append({"spherical": round_id, "plan": plan_json, "logs": logs, "verdict": verdict})
if verdict.get("motion") == "submit": break
plan_json = refine(process, logs) or plan_json
last = synthesize(process, hint[-1]["logs"], plan_json.get("final_format", "Reply: "))
return {"last": last, "hint": hint}
We implement the complete HRM loop: we plan subgoals, remedy every by producing and working Python (capturing RESULT), then we critique, optionally refine the plan, and synthesize a clear last reply. We orchestrate these rounds in hrm_agent, carrying ahead intermediate outcomes as context so we iteratively enhance and cease as soon as the critic says “submit.” Take a look at the Paper and FULL CODES.
ARC_TASK = textwrap.dedent("""
Infer the transformation rule from practice examples and apply to check.
Return precisely: "Reply: ", the place is a Python listing of lists of ints.
""").strip()
ARC_DATA = {
"practice": [
{"inp": [[0,0],[1,0]], "out": [[1,1],[0,1]]},
{"inp": [[0,1],[0,0]], "out": [[1,0],[1,1]]}
],
"take a look at": [[0,0],[0,1]]
}
res1 = hrm_agent(ARC_TASK, context={"TRAIN": ARC_DATA["train"], "TEST": ARC_DATA["test"]}, price range=2)
rprint("n[bold]Demo 1 — ARC-like Toy[/bold]")
rprint(res1["final"])
WM_TASK = "A tank holds 1200 L. It leaks 2% per hour for 3 hours, then is refilled by 150 L. Return precisely: 'Reply: '."
res2 = hrm_agent(WM_TASK, context={}, price range=2)
rprint("n[bold]Demo 2 — Phrase Math[/bold]")
rprint(res2["final"])
rprint("n[dim]Rounds executed (Demo 1):[/dim]", len(res1["trace"]))
We run two demos to validate the agent: an ARC-style process the place we infer a change from practice pairs and apply it to a take a look at grid, and a word-math downside that checks numeric reasoning. We name hrm_agent with every process, print the ultimate solutions, and in addition show the variety of reasoning rounds the ARC run takes.
In conclusion, we acknowledge that what now we have constructed is greater than a easy demonstration; it’s a window into how hierarchical reasoning could make smaller fashions punch above their weight. By layering planning, fixing, and critiquing, we empower a free Hugging Face mannequin to carry out duties with shocking robustness. We go away with a deeper appreciation of how brain-inspired constructions, when paired with sensible, open-source instruments, allow us to discover reasoning benchmarks and experiment creatively with out incurring excessive prices. This hands-on journey exhibits us that superior cognitive-like workflows are accessible to anybody keen to tinker, iterate, and be taught.
Take a look at the Paper and FULL CODES. Be happy to take a look at our GitHub Web page for Tutorials, Codes and Notebooks. Additionally, be at liberty to comply with us on Twitter and don’t overlook to hitch our 100k+ ML SubReddit and Subscribe to our Publication.
Asif Razzaq is the CEO of Marktechpost Media Inc.. As a visionary entrepreneur and engineer, Asif is dedicated to harnessing the potential of Synthetic Intelligence for social good. His most up-to-date endeavor is the launch of an Synthetic Intelligence Media Platform, Marktechpost, which stands out for its in-depth protection of machine studying and deep studying information that’s each technically sound and simply comprehensible by a large viewers. The platform boasts of over 2 million month-to-month views, illustrating its reputation amongst audiences.
Elevate your perspective with NextTech Information, the place innovation meets perception.
Uncover the most recent breakthroughs, get unique updates, and join with a world community of future-focused thinkers.
Unlock tomorrow’s developments at the moment: learn extra, subscribe to our e-newsletter, and develop into a part of the NextTech neighborhood at NextTech-news.com

