Instructions to use anyforge/ruhui with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use anyforge/ruhui with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="anyforge/ruhui")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("anyforge/ruhui", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Configuration Parsing Warning:Invalid JSON for config file config.json
Ruhui · 如晦
A non-autoregressive System 1 decision engine for Chinese & multilingual text, with calibrated probabilities.
Named after Du Ruhui (杜如晦, courtesy name Keming 克明) of the legendary Fang Mou Du Duan (房谋杜断) pair — Fang Xuanling was the strategist, Du Ruhui the decisive judge. Ruhui inherits the "decisive" half: it makes a fast System 1 decision, generates no text, has nothing to parse, and therefore cannot hallucinate.
What it is
Ruhui answers typed questions — choice, score, noul (yes/no) — over any state (text, email, ticket, or JSON) in a single forward pass, returning a calibrated probability for every option. No text generation, no parsing, no hallucination.
Two backends share the same interface:
| Backend | Architecture | Size | Latency | Strength |
|---|---|---|---|---|
| bert | bidirectional encoder (mmBERT-base) + decision head | 322M | ~33 ms | fast, CPU-friendly, Chinese/English |
| llm | Causal LM (Qwen3.5) + LoRA + PointerHead | 0.8B+ | hundreds of ms | stronger generalization |
Installation
pip install ruhui -U
Python 3.10+. Core deps: torch, transformers, safetensors, huggingface_hub, numpy. The LLM backend additionally needs peft.
Quick Start
llm backend (larger model, stronger generalization)
from ruhui.llm import LLMAgent
# a merged (self-contained) model — no base_dir needed
agent = LLMAgent(checkpoint_dir="/path/to/anyforge/ruhui/0.8B")
# choice task
result = agent.predict(
{"message": "我被重复扣款了,请退款"},
{"intent": {"type": "choice", "instructions": "客户想做什么?",
"criteria": {"refund": "退款", "billing": "账单"}}},
)
print(result["answers"])
# score task
result = agent.predict(
{"message": "我被重复扣款了,客服三天没回复,今天必须解决,不然就取消订阅!"},
{
"frustration": {
"type": "score",
"instructions": "客户有多生气?",
"criteria": ["平静", "有点不满", "明显恼火", "非常愤怒,威胁投诉"],
},
"urgency": {
"type": "score",
"instructions": "这件事有多紧急?",
"criteria": ["不急", "需尽快处理", "紧急且阻塞"],
},
},
)
print(result["answers"])
# noul task
result = agent.predict(
{"message": "不然我就取消订阅,去用你们竞争对手的产品"},
{
"churn_risk": {
"type": "noul",
"instructions": "客户是否威胁要离开或取消?",
},
"refund_requested": {
"type": "noul",
"instructions": "客户是否明确要求退款?",
},
},
)
print(result["answers"])
bert backend (the original, unchanged)
import ruhui
agent = ruhui.load("/path/to/anyforge/ruhui") # hub, or a local directory
result = agent.predict(
{"message": "我被重复扣款了,请退款"},
{
"intent": {"type": "choice", "instructions": "客户想做什么?",
"criteria": {"refund": "退款", "technical": "技术问题", "billing": "账单咨询"}},
"churn_risk": {"type": "noul", "instructions": "客户是否威胁要离开?"},
},
)
print(result["answers"])
details repo: anyforge/ruhui。
How the two backends work
bert backend — encoder + decision head
A bidirectional encoder reads the whole input, then a 2-layer decision head scores each option at its own [MASK] slot, all in parallel. Probabilities come from a softmax over those option slots, trained with RLCD (reinforcement learning from strictly-proper-scoring-rule rewards) so the reported confidence is statistically meaningful.
[CLS] question + [MASK] opt0 [MASK] opt1 ... [SEP] state [SEP]
→ bidirectional encoder
→ gather the [MASK] slot vectors
→ parallel scorer → softmax → calibrated probabilities
llm backend — Causal LM + PointerHead (KEV-style)
A frozen causal LM runs prefill-only (never generates tokens). Each question becomes a branch sharing one state prefix, isolated by a block-causal mask. A pointer head then reads the <decide> position and "points" at the option boundary tokens — the attention scores become the option probabilities.
[state] [q: instr <opt>opt A</opt> <opt>opt B</opt> <decide>]
→ Causal LM (prefill only)
→ PointerHead: q(decide) · k(option) → logits → softmax
The LoRA adapter is folded into the base weights at inference (or merged permanently with merge_model.py).
Decision primitives
| Primitive | Output |
|---|---|
choice |
top label + full probability distribution + confidence |
score |
expected level on an ordinal rubric |
noul |
calibrated P(true) |
Confidence is normalized entropy (1 − H(p)/log K), so it is safe to gate on:
if conf >= 0.85:
route_automatically(dept) # high confidence
else:
escalate_to_human(dept) # low confidence
Fine-tuning
llm backend (KEV-style)
# 1. convert soft labels to KEV-format training data
python scripts/convert_to_kev.py --soft_dir <dir> --out datas/train.jsonl
# 2. fine-tune from an existing checkpoint (delta mode)
python scripts/finetune.py \
--data datas/train.jsonl \
--base Qwen/Qwen3.5-0.8B-Base \
--init_from anyforge/ruhui/0.8B \
--out runs/ruhui-0.8b \
--epochs 2 --device cuda
# 3. resume if interrupted
python scripts/finetune.py ... --resume
# 4. merge LoRA into the base weights (bf16 halves the size)
python scripts/merge_model.py \
--checkpoint runs/ruhui-0.8b \
--base Qwen/Qwen3.5-0.8B-Base \
--out runs/ruhui-0.8b-merged \
--dtype bf16
bert backend (Laya-style)
python scripts/train.py \
--model_dir <base_model_dir> \
--train_items <train_items.pt> \
--output_dir <output_dir> \
--epochs 4
Repository layout
ruhuipro/
ruhui/
bert/ # encoder backend (agent / router / common / presets / ...)
llm/ # LLM backend (model / api / checkpoint / train / data / agent)
scripts/
convert_to_kev.py # soft labels → KEV format
finetune.py # LLM fine-tune (--init_from / --resume)
merge_model.py # LoRA merge + dtype control
train.py # bert fine-tune
tests/
Model repositories
- Hugging Face:
anyforge/ruhui(root = bert model;0.8B/= LLM 0.8B merged model) - ModelScope:
anyforge/ruhui(same layout)
Acknowledgments
- Laya (NandhaKishorM/laya, Apache 2.0) — the non-autoregressive System 1 decision paradigm and RLCD training that the bert backend is forked from.
- KEV (jaredpalmer/kev, Apache 2.0) — the Causal LM + LoRA + PointerHead architecture that the llm backend is built on.
License
Apache 2.0. Developed by AnyForge.
- Downloads last month
- -