Translation
MLX
Core ML
ONNX
Safetensors
Japanese
Chinese
jmangatranslator-fast
manga
japanese
chinese
Instructions to use muscgab/JMangaTranslator-Fast with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use muscgab/JMangaTranslator-Fast with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] hf download muscgab/JMangaTranslator-Fast --local-dir JMangaTranslator-Fast
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
File size: 3,366 Bytes
3d92ad2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | """Shared data loading for the GalTransl-v4-4B vs R2 comparison (Titan Xp, user 2026-10-06 20:0x).
Tasks
m109 Manga109-s real-OCR set (artifacts/m109_ocr_20261006/sample.jsonl, 3,817 boxes); inputs clean / nar / mocr;
one box = one request (deployment-like, no context).
murasaki Murasaki benchmark light-novel paragraphs (100 Short ~190 chars + 100 Long ~790 chars, human references);
paragraphs are cut into sentences by split_ja(); the hypothesis is the concatenation of segment outputs.
"""
from __future__ import annotations
import json
import os
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
M109 = ROOT / "artifacts/m109_ocr_20261006"
MURASAKI = ROOT / "benchmarks/Murasaki-benchmark/data"
OUT = Path(os.environ.get("SAKURA_OUT", ROOT / "artifacts/sakura_cmp_20261006")) # smoke tests use another dir
_END = "。!?!?…"
_CLOSE = "」』))】〉》"
def split_ja(text: str, max_len: int = 120) -> list[str]:
"""Sentence segments, never inside 「」『』(): outside brackets, cut after sentence-final punctuation and after a
closing bracket that ends a quote (like one speech balloon / one line); segments longer than max_len are cut again
after 、 or ,."""
segs, cur, depth = [], "", 0
for i, ch in enumerate(text):
cur += ch
nxt = text[i + 1] if i + 1 < len(text) else ""
if ch in "「『((【":
depth += 1
elif ch in _CLOSE and depth:
depth -= 1
if depth == 0 and nxt not in _END and nxt not in _CLOSE:
segs.append(cur); cur = ""
elif depth == 0 and ch in _END and nxt not in _END and nxt not in _CLOSE:
segs.append(cur); cur = ""
if cur:
segs.append(cur)
out = []
for s in segs:
while len(s) > max_len:
cut = max(s.rfind("、", 0, max_len), s.rfind(",", 0, max_len))
cut = cut + 1 if cut > 0 else max_len
out.append(s[:cut]); s = s[cut:]
if s:
out.append(s)
assert "".join(out) == text
return out
def load_m109() -> list[dict]:
return [json.loads(x) for x in open(M109 / "sample.jsonl", encoding="utf-8")]
def load_murasaki() -> list[dict]:
rows = []
for cat in ("short", "long"):
for k, x in enumerate(open(MURASAKI / f"dataset_{cat}.jsonl", encoding="utf-8")):
r = json.loads(x)
rows.append({"id": f"{cat}{k:03d}", "category": r["category"], "src": r["src"], "ref": r["ref"],
"segs": split_ja(r["src"])})
return rows
def write_jsonl(path: Path, rows: list[dict]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
for r in rows:
f.write(json.dumps(r, ensure_ascii=False) + "\n")
def strip_think(s: str) -> str:
return re.sub(r"<think>.*?</think>\s*", "", s, flags=re.S).strip()
LUNA_SETS = ("dev", "heldout", "luna1k", "manga200")
LUNA = ROOT / "artifacts/ar_mt_20261005/data_v2_ext"
def load_luna(name: str) -> list[dict]:
"""Our standard sets (Luna manga lines + Manga200); references are in the Luna teacher's style, which our model was
trained on, so these favour our model."""
return [json.loads(x) for x in open(LUNA / f"eval_{name}.jsonl", encoding="utf-8")]
|