HachimiMT-60-QT: Chinese→Vietnamese translation with a perfectly consistent "convert" voice
The "classical register" edition of
HachimiMT-60: it translates
Chinese web novels into Vietnamese using the
truyện convert pronoun register —
ta, ngươi, hắn, nàng, tỷ tỷ, ca ca… (the archaic Sino-Vietnamese address style
that Vietnamese web-novel readers know by heart) — and
keeps that voice perfectly
stable from the first line of a chapter to the last.
What's different from the base model?
Ordinary MT models (including base HachimiMT-60) have a habit that drives novel
readers crazy: they switch address style mid-chapter. The same character is
"ngươi" (archaic you) in one line and suddenly "cậu" (modern you) in the next;
the narrator says "ta" (I, archaic) in one paragraph and "tôi" (I, modern) in
another.
This QT edition was trained on data whose entire pronoun system was normalized, so
the voice never flips. Real output, same chapter, same interview scene
(base HachimiMT-60 vs this model):
| Source | Base model | QT model |
|---|
| 你为什么要报考我们的学校? | Tại sao ngươi lại muốn thi vào trường của chúng ta? | Tại sao ngươi phải thi vào trường của chúng ta? |
| 你成绩没有问题…… (very next line) | Thành tích của cậu không thành vấn đề… ← voice flips! | Thành tích của ngươi không có vấn đề gì… |
| 我来给你介绍介绍这里的福利吧 | Để tôi giới thiệu … cho cậu nhé, chúng tôi… | Để ta giới thiệu … cho ngươi nhé, chúng ta… |
| 张羽……他感觉…… (narration) | Trương Vũ… cậu cảm thấy… ← modern "cậu" in narration | Trương Vũ… hắn cảm thấy… |
Measured on 7 chapters across 7 genres (538 lines): in the you-register class the
base model flips voice at ~24% of line transitions; this model: 0%. The
I, we and third-person classes also drop to zero.
Stress tests
Four pronouns in one sentence — nothing gets mixed up:
他说你不懂她的心思,我们都别插手了。
→ Hắn nói ngươi không hiểu tâm tư của nàng, chúng ta đều đừng nhúng tay vào.
(he→hắn, you→ngươi, she→nàng, we→chúng ta)
A long multi-clause paragraph — where the base model mixes two voices inside a
single paragraph:
张羽同学,我们了解到你的家庭情况恐怕不足以负担这边的学费。不过我们为贫困生提供了优惠的贷款服务,只要你愿意抵押一些不重要的器官就行……
| Translation |
|---|
| Base | Bạn học Trương Vũ, chúng tôi hiểu được tình hình gia đình của bạn… Tuy nhiên, chúng ta đã cung cấp dịch vụ vay… chỉ cần bạn… ← two registers in one paragraph |
| QT | Bạn học Trương Vũ, chúng ta biết được tình hình gia đình của ngươi… Nhưng chúng ta đã cung cấp dịch vụ vay vốn ưu đãi… chỉ cần ngươi chịu thế chấp một số nội tạng không quan trọng là được... |
When to use it
- ✅ Xianxia, xuanhuan, historical, danmei — or any genre where you want the
convert voice all the way through.
- ⚠️ Modern-setting stories also come out in the archaic voice ("Sao ngươi chưa
nghỉ ngơi?") — that is by design. If you want context-appropriate natural
register instead, use the
base model.
Deliberate trade-offs (documented so nothing surprises you):
- 我们/咱们 both become "chúng ta" (the inclusive/exclusive we distinction is dropped).
- Modern intimate address (anh/em between lovers) mostly becomes ta/ngươi.
Known limitations (real example, not hidden)
Rare proper nouns and coined terms can come out with a shifted syllable or a
literal translation — a limitation of every model in this size class, not specific
to the QT edition. Example, the spirit-beast name 【异瞳金丝猴】 (reference:
Dị Đồng Kim Ty Hầu): the base model outputs "Kim Ti Hầu", this model outputs
"Kim Tơ Hầu" (literal reading of 丝). If your novel is full of first-time rare
names, spot-check them.
Quick start (Python)
1from transformers import AutoTokenizer, MarianMTModel
2import torch
3
4repo = "ngocdang83/HachimiMT-60-QT"
5tokenizer = AutoTokenizer.from_pretrained(repo)
6model = MarianMTModel.from_pretrained(repo).eval()
7
8src = "你成绩没有问题,但想要进嵩阳高中,光靠校内考试成绩是远远不够的。"
9inp = tokenizer(src, return_tensors="pt", truncation=True, max_length=256)
10with torch.inference_mode():
11 out = model.generate(**inp, max_new_tokens=300, num_beams=4, early_stopping=True)
12print(tokenizer.decode(out[0], skip_special_tokens=True))
13# "Thành tích của ngươi không có vấn đề gì, nhưng muốn vào trường trung học
14# Tung Dương, chỉ dựa vào điểm thi trong trường là còn xa mới đủ."
💡 Decoding tip: do not set no_repeat_ngram_size with this model — it
forces the decoder to avoid repeating n-grams and tends to mangle proper names
(Lý Giáng Thiên → Lý Giáng Dương). The defaults above are what we ship with.
Fast CPU inference (CTranslate2)
The repo ships an INT8 export under ct2-int8_float32/ — several times faster on
machines without a GPU:
1import ctranslate2
2from pathlib import Path
3from huggingface_hub import snapshot_download
4from transformers import AutoTokenizer
5
6repo = "ngocdang83/HachimiMT-60-QT"
7path = Path(snapshot_download(repo, allow_patterns=[
8 "config.json", "source.spm", "target.spm", "vocab.json",
9 "tokenizer_config.json", "ct2-int8_float32/*",
10]))
11tokenizer = AutoTokenizer.from_pretrained(path)
12translator = ctranslate2.Translator(str(path / "ct2-int8_float32"),
13 device="cpu", compute_type="int8_float32")
14
15src = "你放心吧,人家是大公司,不会骗人的。"
16toks = tokenizer.convert_ids_to_tokens(tokenizer(src).input_ids)
17res = translator.translate_batch([toks], beam_size=1, max_decoding_length=256)
18print(tokenizer.decode(tokenizer.convert_tokens_to_ids(res[0].hypotheses[0]),
19 skip_special_tokens=True))
20# "Ngươi yên tâm đi, người ta là công ty lớn, sẽ không lừa người đâu."
The Hachimi family
| Model | Use when |
|---|
| HachimiMT-60-zh-vi | Natural, context-dependent register |
| HachimiMT-60-QT (this) | One perfectly stable convert voice |
| Demo Space | Try it in the browser |
Technical details (56.96M params, Marian encoder-decoder, runs fine on CPU or GPU)
are in config.json. License CC-BY-4.0 — use freely with attribution.