Skip to content
←Back to Blog
Tencent Hunyuan Open-Sources Hy Memory 2.0: A 3B-Active Specialist Model Takes Over Memory Writing
Agent MemoryLLM AgentReinforcement Learning

Tencent Hunyuan Open-Sources Hy Memory 2.0: A 3B-Active Specialist Model Takes Over Memory Writing

Tencent Hunyuan open-sources Hy Memory 2.0: the 3B-active writer model Hy-Memory-30B-A3B, the hy-memory SDK, and local-first MemHub; a 55.49 macro average over four harnesses edges out Opus 5.

meng shao (@shao__meng)October 16, 202618 min read22 views
ZH

Three Pieces Behind One Tweet: Model, SDK, Desktop App

Lead: a thread by meng shao (@shao__meng) on X (Oct 16, 2026, quoting the official Tencent Hunyuan launch tweet). Beyond the tweet, this post reads the Hy-Memory repository, the Hugging Face model card, the technical report arXiv:2610.22196, and the MemHub docs.

On October 16, 2026, Tencent Hunyuan open-sourced "Hy Memory 2.0" as three artifacts at once: Hy-Memory-30B-A3B, a MoE model that does memory writing and nothing else (30B total, ~3B active parameters); the hy-memory SDK, a programmable memory framework (PyPI 2.0.4, Apache-2.0); and MemHub (v1.0.4), a local-first desktop app plus CLI. meng shao's tweet compresses the release into one judgment: instead of wrapping a general-purpose LLM in a memory framework (the Mem0 / MemOS pattern), use a cheap specialist model to perform memory writing on the general model's behalf - cheaper, and portable across frameworks.

Infographic from the tweet showing the three layers of Hy Memory 2.0: writer model, SDK, MemHub, with benchmark scores
The tweet's infographic: the three layers of Hy Memory 2.0 - writer model, memory framework, desktop product.

That judgment deserves unpacking, because memory writing is the most underrated and most expensive stage of any long-term memory system.

Why the Write Path Is the Most Expensive Stage

Every long-term memory system decomposes into three stages: a writer turns an interaction into persistent memory operations; a retriever selects records relevant to a future query; a reader (answer model) responds using those records.

flowchart LR
  W["writer: what to keep, how to phrase it, how to update old state"] --> B[("memory bank")]
  B --> R["retriever"]
  R --> A["reader / answer model"]
  A --> Q["answer"]

The mainstream implementation puts a general-purpose LLM behind a long, framework-specific prompt. Two problems follow. The first is informational: a framework cannot recover what the writer omitted, and no reader, however strong, can infer a fact that was never stored; conversely, storing everything indiscriminately inflates cost and creates retrieval interference. The second is economic: writing is the high-frequency call - every turn and every tool call passes through the writer, while reads are comparatively sparse. Billing a flagship model for that duty scales linearly with conversation length.

So Hy Memory 2.0 bets that writing can be trained as a transferable model capability rather than a collection of framework-specific prompt heuristics. The evidence in the tech report: after training inside Mem0, MemOS, and Hy-Memory harnesses, the same model takes over the write path of EverMemOS, a framework it never saw during training.

Hy-Memory-30B-A3B: A MoE That Only Writes

The model is the Hy3-family 30B-A3B instruction-tuned checkpoint: 30B total parameters, ~3B active, so serving cost resembles a 3B model - the shape a high-frequency write call can actually afford.

Model configuration (Hugging Face config.json)
ItemValue
ArchitectureHYV3 MoE
Layers / hidden48 / 2048
Experts128 routed, top-8 active, plus 1 shared; expert hidden 768
AttentionGQA, 32 query heads / 4 KV heads, head_dim 128
Vocab / max position120,832 / 262,144

Stage 1: Memory On-Policy Distillation

OPD does not ask the teacher to generate an ideal trajectory. The frozen Hy3 flagship teacher runs a forward pass over the student's own sampled token stream and returns its top-50 distribution; the loss is a top-k approximation to reverse KL on student-visited prefixes:

$$\mathcal{L}_{\mathrm{OPD}}=\frac{1}{|\mathcal{T}|}\sum_{(i,j)\in\mathcal{T}}\ell_{i,j},\qquad \ell_{i,j}=\sum_{v\in\mathrm{top}\text{-}50}\pi_{\theta}(v\mid x_{i,<j})\left[\log\pi_{\theta}(v\mid x_{i,<j})-\log\pi_{T}(v\mid x_{i,<j})\right]$$

For memory writing, on-policy pays off beyond token prefixes: the bank carried in each chunk's prompt was also written by the student, so the supervision distribution matches the deployment distribution. Configuration: 2 rollouts per row, constant learning rate 1e-6, entropy coefficient 0.005; every LLM call inside one harness write is kept as an explicit segment with position ids reset at call boundaries, so independent calls never merge into one artificial conversation. RL initializes from OPD step 375.

Stage 2: Attributed Memory Reinforcement Learning

RL runs the same harness configurations. Per window (at most five chunks), eight rollouts start from independent copies of the same parent bank, write all chunks, get examined by reward questions, and receive per-chunk scores; the highest-scoring final bank is promoted as the initial bank of the next window in the same sequence. On-policy holds at two levels: tokens are sampled from the current policy, and future prompts contain banks produced by that policy.

Tech report Figure 1: two-stage training with the rollout grid, per-chunk scores, column-wise advantage normalization, and carry-forward of the best final bank
Tech report Figure 1: both stages execute inside the deployed harness configurations. In the rollout grid each cell is the bank after chunk t of rollout i, shaded by its chunk score; advantages normalize within each column (dashed group).
flowchart TD
  P["parent bank M(t-1)"] --> R1["rollout 1: writes all chunks in window"]
  P --> R8["rollout 8: writes all chunks in window"]
  R1 --> S1["per-chunk scores s_1[t]"]
  R8 --> S8["per-chunk scores s_8[t]"]
  S1 --> W{"rank by sum_t s[t]"}
  S8 --> W
  W --> N["best final bank = parent of next window"]
  W --> D["other seven banks discarded"]

The reward has three parts. The per-chunk recall reward prm averages judge scores over positive probes and trap probes (a chunk with no valid probes scores 0, not 1):

$$\mathrm{prm}[t]=\frac{\sum_{i\in R_{t}}z_{i}+\sum_{j\in P_{t}}z_{j}}{|R_{t}|+|P_{t}|}$$

The attributed outcome reward orm uses gold facts to map "how much evidence the answer recovered" back to the chunk that introduced it, averaged so that annotators cannot inflate a chunk by writing more questions about it:

$$\mathrm{orm}[t]=\frac{1}{|Q_{t}|}\sum_{q\in Q_{t}}c_{q}[t]$$

The bank-growth penalty pen applies exponential pressure on token growth ratio (not entry count - lengthening existing records grows a bank too):

$$x_{t}=\mathrm{clip}\!\left(\frac{g_{t}-\ell_{h}}{u_{h}-\ell_{h}},\,0,\,1\right),\qquad \mathrm{pen}[t]=\frac{e^{3x_{t}}-1}{e^{3}-1}$$

The three combine into a per-chunk score with $w_{\mathrm{prm}}=1$, $w_{\mathrm{orm}}=2$, $w_{\mathrm{pen}}=0.3$, $\gamma=0$ - gold-fact attribution already handles delayed cross-chunk evidence, so broadcasting future recall scores backward would only add noise:

$$s[t]=w_{\mathrm{prm}}\sum_{k\geq t}\gamma^{k-t}\,\mathrm{prm}[k]+w_{\mathrm{orm}}\,\mathrm{orm}[t]-w_{\mathrm{pen}}\,\mathrm{pen}[t]$$

Advantages normalize per chunk column (chunk-level GRPO) instead of one score per trajectory: the eight rollouts share a bank only at chunk 0, and afterwards each rollout observes the bank its own earlier actions created, so a trajectory-level score would again broadcast one judgment over all of its writes.

$$A_{i,t}=\frac{s_{i}[t]-\mu_{t}}{\sigma_{t}+\epsilon}$$

Each rollout casts exactly one vote per chunk: if a multi-stage harness made three LLM calls for that chunk, all three segments receive the same advantage but do not count as three independent observations - otherwise the policy could manipulate the baseline by changing its call count. Groups with fewer than two valid rollouts get zero advantage.

Reward Data: 164k Probes Grown From the Failure Surface

Using only a benchmark's final questions as reward is a low-density learning problem: a long interaction may contain hundreds of useful facts but only a few questions; an unasked write receives no evidence, and a failed answer cannot distinguish omission, bad wording, stale-state confusion, retrieval failure, or reader failure. Reward items are therefore constructed from the failure surface of memory writing, annotated in two passes:

The two annotation passes and the reward each feeds
PassAnnotator contextOutput and target
Per-chunk probe (PRM)Full text of chunk t plus extracted facts of chunks t-1 and t-2Atomic facts, probes, traps, rubrics; tests whether chunk t was written precisely and remains recoverable
Cross-chunk outcome (ORM)Earlier-sequence facts plus all facts in the current windowQuestions, evidence chunks, gold facts, rubrics; tests relations spanning chunks or sessions

The PRM pass sees only the two preceding chunks' facts, not full history - a measured decision. Full-history annotation consumed 33x more input tokens, while the two-chunk context yielded 25% more proper nouns and 59% more numbers per extracted fact: with the whole sequence in view, annotator attention spreads and facts turn generic, which is exactly the over-generalization failure the probes exist to catch.

Per-chunk failure-surface probe taxonomy
Probe typeWhat the reward tests
SpecificityExact names, numbers, titles, versions, paths, and entities survive writing
Semantic precisionNegation, scope, and event meaning are not inverted
Plain recallA durable explicit fact remains answerable
Secondary dimensionA dominant topic does not erase a smaller detail
TransitionThe new state and the state it supersedes are both represented
Should-not-storeGreetings, vague praise, and generic assistant text are absent

Trap probes ask about content that should never have entered long-term memory; the reference answer is "the bank contains no such record." If the writer stores irrelevant chatter, retrieval exposes it and the answer is graded wrong. Traps complement the growth penalty: the penalty discourages volume, traps test semantic selectivity, and compressing irrelevant text into a shorter entry does not dodge them.

Harness-level statistics of the RL reward artifact
ConfigurationProcessed unitsReward items
Hy-Memory / Chat3,182 windows; 14,519 chunks41,990 recall; 2,769 traps; 15,281 ORM
Hy-Memory / Working1,971 windows; 8,902 chunks25,272 recall; 1,537 traps; 9,740 ORM
Hy-Memory / Coding1,154 windows; 5,187 chunks14,348 recall; 178 traps; 5,337 ORM
Mem03,182 windows; 14,516 chunks41,416 recall; 1,969 traps; 15,228 ORM
MemOS3,182 windows; 14,492 chunks41,550 recall; 2,146 traps; 15,241 ORM
Total12,671 windows; 57,616 chunks164,576 recall; 8,599 traps; ~60.8k ORM

The final artifact also carries 222,395 chunk-level gold-fact references. Gold facts are visible only to the outcome judge - never inserted into the bank, the retrieval query, or the answer model's prompt. A discriminability check requires the judge to rank five synthetic answers per item in the expected order (reference and paraphrase full credit, partial answer partial credit, distractor or refusal zero); in the pilot, faithful paraphrases retained an average score of 0.90.

Training system: 16 nodes x 8 H20 GPUs (128 GPUs); a batch is 64 windows x 8 rollouts = 512 trajectories; PPO-style clipped surrogate with chunk-level GRPO advantages, aggregated as sequence mean then token mean, no KL penalty; constant learning rate 5e-6; MoE routing from the rollout is replayed during training; context is 28,672 prompt tokens plus 4,096 response tokens.

The hy-memory SDK: Three Scenes, Three Memory Shapes

Hy Memory architecture: left, the WRITE/STORE/SEARCH/SYSTEM2 pipeline of the seven-layer chat memory; right, the two-layer working/coding memory with the version chain
Hy Memory architecture: add() / search() pass a scene router, then enter the Chat or Working / Coding pipeline; orange blocks are Coding-only, and removing them yields Working.
The three memory scenes
sceneTarget tasksMemory shape
chatCasual talk, personal info, preferences, general QALayered memory (L0-L7)
workingDocuments, spreadsheets, research, financial analysis, content creation, computer operationTwo layers: session facts + reusable experiences
codingCoding, debugging, testing, builds, API/SDK work, scripts, SQLSame two layers plus a code version-evolution chain (diff chain)

Chat: L0-L7 Cognitive Memory

For personal long-term memory, raw dialogue is abstracted layer by layer into facts, summaries, profiles, and higher cognitive structures. Note the numbering starts at L0, and L4/L5 are reserved:

Chat memory layers
LayerNameContent
L0BASIC_INFOBasic information
L1RAWRaw dialogue (append-only)
L2FACTAtomic facts (versioned, immutable records)
L3SUMMARYSession summaries
L4 / L5IDENTITY / KNOWLEDGEReserved
L6SCHEMAMental models (abstract narrative templates, graph layer)
L7INTENTIONProspective intentions (with expiry; become plain facts afterwards)

Three processing modes: lite embeds and retrieves raw memories with zero LLM calls and ignores scene - pure vector RAG; pro adds LLM extraction and reconcile-based conflict handling, with an optional graph store (off by default); ultra adds System 2 schema induction and a cross-domain sweeper triggered explicitly via evolve(), with the graph store auto-enabled. On the read side, search_mode="default" always routes to chat with zero LLM calls; only agentic mode performs scene classification, query rewriting, and time-range parsing.

Working: Fact Layer + Experience Layer

One tool-using session produces two layers at once. The fact layer (WorkingFact) records what this session did - exactly one entry per session, no threshold, guaranteeing "what was done is always remembered." The experience layer (Experience) records approaches reusable for similar future tasks - 0 to N entries that must pass a value threshold, handling "what was learned can be reused." The layers cross-link (fact.derived_experience_ids to experience.source_fact_ids); superseded facts are kept in a superseded state and traceable through a task-progress chain.

Coding: Two Layers + a Version-Evolution Chain

Coding reuses the Working pipeline and schema with three differences: an extraction spec aimed at software engineering (subjects must be code or decisions; record precise coordinates - file / function / branch - rather than pasting code); fully isolated storage (coding_memory_cv.db and *_cv vector collections); and the version-evolution chain.

The chain exists for a concrete reason: the fact layer deliberately does not paste code, spending its budget on coordinates, so a reverted version of the code never appears in facts - and that version is often neither in the working tree nor in HEAD, unreadable after the fact. The chain stores every revision's real diff with zero LLM calls, and acts as a decorator, not a retriever: the vector layer decides which facts to return, and the chain merely attaches every revision of the code those facts touch (the user's original words plus the real diff per revision). Sources are local Git diffs or deterministic replacement actions carrying path / old / new in tool traces; one thread corresponds to "a block in a function in a file on a branch," isolated by user_id and workspace_id.

pip install hy-memory                 # core (ChromaDB + Kuzu); latest is 2.0.4
pip install "hy-memory[all]"          # + Qdrant / FAISS / Neo4j / MySQL cache / local rerank

export MEMORY_LLM_MODEL="deepseek-chat"            # any OpenAI-compatible endpoint
export MEMORY_EMBEDDER_MODEL="text-embedding-v3"
export MEMORY_EMBEDDING_DIMS=1024
from hy_memory import HyMemoryClient

client = HyMemoryClient(mode="pro")
client.add("The user likes sci-fi films, especially Interstellar.", user_id="user_1")

results = client.search("What kind of movies does the user like?", user_ids=["user_1"], limit=10)
for mem in results["memories"]["normal"]:        # profile / normal / proactive channels
    print(f"  [{mem['score']:.2f}] {mem['content']}")

# coding scene: writes must carry tool-call traces; returns facts / experiences / chain
result = client.search("Which timeout implementation was finally kept?",
                       scene="coding", user_ids=["user_123"],
                       workspace_id="github.com/example/service",
                       branch="fix/search-timeout", limit=5)
result["facts"], result["experiences"], result["chain_block"]

MemHub: Cross-Tool Memory as a Local-First Product

MemHub launch visual with the One Memory wordmark
MemHub: pools authorized conversation and operation history from multiple AI apps into one local memory.

MemHub is the SDK's end-user form: one install, one runtime, one data directory, many clients. It pools user-authorized dialogue and coding traces from AI apps (Claude Code, Cursor, Codex, OpenCode, Qwen Code, and others) into a locally managed runtime and data directory, then serves governed cross-app memory recall to authorized hosts - preferences learned in Cursor become available to Claude Code.

Notable engineering and privacy boundaries: the Python Core is the only memory data plane and the only writer to the business database; source reading, model processing, and host reading are three independent authorization boundaries; the product performs no screen, Accessibility/AXTree, OCR, keyboard/mouse, clipboard, or background audio capture; SQLite data lives in ~/.one-memory by default. The npm package memhub-cli ships only a ~384 KB bootstrap CLI - postinstall downloads no runtime, registers no service, and touches no shell profile; the full runtime is downloaded and verified only when the user explicitly runs memhub install. Platforms: Linux x64/arm64 and macOS (signed and notarized); Windows is unsupported. Still preview-stage.

Official MemHub demo: one-click app onboarding, continuous sync of new conversations, and global memory across apps.

Reading the Numbers: Four Harnesses, Six Metrics, One 20% Subsample

Evaluation changes only the writer: harness version and prompts, retrieval configuration, answer model, and judge are all fixed, and every writer builds its bank from empty. Each benchmark in the main matrix runs on a fixed 20% subsample; a harness score is the equal-weight mean of six metrics (LoCoMo Judge, LongMemEval, PersonaMem-v2, Travel SPS, Shopping PS, CMB), and the overall score is the equal-weight mean of the four harness scores.

Cross-harness macro-average bar chart: Hy-Memory-30B-A3B ranks first on Mem0, Hy-Memory, MemOS, and EverMemOS
Cross-harness macro averages on the fixed 20% benchmark subsamples; EverMemOS is held out from training.
Cross-harness macro averages (six-metric means, fixed 20% subsamples)
Memory writerMem0Hy-Mem.MemOSEverMem.Avg.
Hy-Memory-30B-A3B54.0260.5550.5156.8955.49
Claude Opus 553.4360.5350.5054.0454.62
DeepSeek V4.1 Flash49.7360.2049.1755.4753.64
Hy345.9958.0650.1952.3051.63
Qwen3.6-35B-A3B47.5155.8747.3650.7550.37
Hy3-A3B Base40.2050.3949.0550.9847.66
Qwen3-30B-A3B39.8145.6745.4446.5744.37

Against Opus 5 the macro gain is +0.87 (Mem0 +0.60, Hy-Memory +0.02, MemOS +0.01, EverMemOS +2.86). The report says plainly that the 0.01-0.02 margins on MemOS and Hy-Memory are parity, not statistically resolved differences. The harder evidence is twofold: +2.86 on held-out EverMemOS (driven by Travel SPS +10.65 and CMB +13.66), which separates model-level writing skill from memorized harness protocols; and +7.84 over the true initialization checkpoint (Hy3-A3B Base at 47.66), which shows the training method itself works.

Division of labor among memory-RL peers (summary of tech report Table 1)
MethodWhat is trainedReward shape
Memory-R1Memory manager + answer agentFinal-answer reward
MemAgentRecurrent textual compression (memory as internal model state)Terminal verifiable reward
Mem-alphaConstruction policy over a multi-component bankDownstream QA + format / compression / operation-quality rewards
MemCoEGuideline and evolution policy for personalization memoryGuideline-aligned process feedback
Hy-Memory-30B-A3BWriter only; reader and judge frozen; multiple existing harnessesPer-chunk probes + gold-fact attributed ORM + traps and growth penalty + chunk-level GRPO

Honest boundaries to keep in view: these are self-reported numbers from the official tech report on fixed 20% subsamples, and independent replication is still outstanding. The report explicitly lists ablations not yet done: chunk-level vs window-level GRPO, gold-fact attribution vs broadcast ORM, probes plus traps vs probes only, the bank-growth penalty, binary vs rubric rewards, RL initialization from OPD vs generic SFT, and single-harness vs mixed-harness training. Attribution is evidence-based rather than counterfactual - recovering a gold fact does not prove a specific write caused the answer - and pooled scores can hide whether gains come from extraction, update, deletion, reconciliation, or retrieval-facing representation.

Two corrections to the tweet itself. First, the SDK's chat hierarchy is L0-L7 (with L4/L5 reserved), not L1-L7. Second, "about +11 over the same-architecture base Qwen3-30B-A3B" mixes up reference points: RL's true starting point is Hy3-A3B Base (47.66 to 55.49, +7.84); Qwen3-30B-A3B (44.37) is only a size-matched open reference, so 55.49 minus 44.37 (about 11.1) measures the whole training recipe against a same-size reference, not the gain over the initialization checkpoint. The tweet's other figures (55.49 vs 54.62; EverMemOS 56.89 vs 54.04) match the report.

Nine Silent Failures That Looked Healthy

Section 9 of the tech report reads like an engineering log: each failure looked fine on the metrics until some invariant was checked.

  • A bank that did not persist across windows still left files on disk and produced nonzero rewards. Check: reopen the checkpointed bank and verify a known record before training.
  • A teacher returning no top-k values still returned successful requests, but OPD gradients were zero. Missing teacher fields must raise; monitor teacher-token coverage.
  • When the per-chunk mapping was absent, a fallback broadcast one score to every segment. Missing chunk-to-segment mappings must raise.
  • A configuration omitted from a hard-coded schedule still had valid artifacts on disk. Schedule manifests must be audited against the declared harness set.
  • String rules grading semantics produced a plausible aggregate reward. Semantic conditions belong in judge rubrics, not substring code.
  • A "read all" that silently paginated made the bank entry count plateau at a default limit. Pagination and token accounting must be tested explicitly.
  • Failed writes checkpointed as empty were marked complete. Platform faults must be retryable and excluded from denominators.
  • Sandboxes sharing a trajectory identity completed requests attached to the wrong rollout. Every request must validate bank and trajectory identity.
  • Malformed output treated as an environment error made bad actions disappear from training. Policy mistakes should remain valid low-reward trajectories.

The governing rule: a bad policy action must receive low reward; a platform failure must not be misrepresented as policy behavior.

Limitations and What Comes Next

Beyond the missing ablations, the report concedes: credit is truncated across optimizer steps, so earlier-bank errors cannot receive retrospective gradient; one-vote grouping stabilizes the baseline, but multi-call chunks still carry more loss mass; rubric rewards reduce sparsity yet still need human-agreement and judge-sensitivity audits; the reward artifact covers Chat, Working, and Coding but not every long-term-memory workload; EverMemOS is the single held-out framework; and repeated training seeds remain future work.

Running It Yourself

# Model: serve with vLLM (report tested v0.31.0); served-model-name must be hy-memory
vllm serve tencent/Hy-Memory-30B-A3B --served-model-name hy-memory
from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="EMPTY")
resp = client.chat.completions.create(
    model="hy-memory",
    messages=[
        {"role": "system", "content": "Extract explicit user facts and preferences ... "
                                      'Return only a JSON object with a "memories" list.'},
        {"role": "user", "content": "My name is Alex. I live in Seattle ..."},
    ],
    temperature=0.0, max_tokens=512,
    extra_body={"chat_template_kwargs": {"reasoning_effort": "no_think"}},  # no-think mode
)
# MemHub: npm bootstrap, then install the runtime explicitly
npm i -g memhub-cli
memhub install && memhub serve      # start / stop / status / doctor / uninstall

For teams building agent infrastructure, the reusable part of this release is probably not the 55.49 itself but three plainer things: a methodology that turns the writer from prompt craft into an evaluable, trainable, swappable model capability; an engineering schema that splits memory shapes by scene and controls bank noise with value thresholds and diff chains; and the honesty of publishing nine silent failures alongside the results.

Sources: meng shao (@shao__meng) on X (2026-10-16); Tencent-Hunyuan/Hy-Memory README and docs; Hugging Face model card tencent/Hy-Memory-30B-A3B; tech report arXiv:2610.22196; MemHub README. All benchmark numbers come from the official report's fixed 20% subsamples and are self-reported.

As an Amazon Associate, we earn from qualifying purchases.