--- license: apache-2.0 base_model: Qwen/Qwen3-1.7B-Base language: - zh - en pipeline_tag: translation library_name: transformers tags: - translation - qwen3 - zh-en - en-zh - sft - cpo - grpo datasets: - haoranxu/ALMA-Human-Parallel - haoranxu/X-ALMA-Parallel-Data --- # Interpreter-Qwen3-1.7B A 1.7B Chinese↔English translation model, trained **SFT → CPO → GRPO**. This model is one half of an A/B pair. The two differ in **exactly two things** — the base checkpoint and the tokenizer — and share the same data, hyperparameters, losses and rewards. The other half is [`Ismantic/Interpreter-Qwen3-1.7B-ReTok`](https://huggingface.co/Ismantic/Interpreter-Qwen3-1.7B-ReTok). | | this model | |---|---| | Tokenizer | Qwen3 native BBPE (151643) | | Chat format | ChatML | | Pipeline | SFT → CPO → GRPO | ## Results (WMT23) | direction | BLEU / COMET | |---|---| | zh→en | 20.31 / 0.8053 | | en→zh | 33.69 / 0.8540 | ### How to read these numbers WMT23 is the primary test set — **WMT22 is excluded**, roughly 17.5% of it leaked into the ALMA SFT data. COMET is `Unbabel/wmt22-comet-da`, which is *also* the GRPO reward, so gains were cross-checked on WMT23/24 + Flores-200 with BLEU and chrF to rule out reward hacking. vLLM greedy decoding is not bit-reproducible; BLEU varies by ~0.1 between runs. Differences at that scale are noise. ## Usage Standard ChatML with a fixed translation instruction; `<|im_end|>` is the stop token. Greedy decoding recommended. ```python import torch from transformers import AutoModelForCausalLM, AutoTokenizer tok = AutoTokenizer.from_pretrained("Ismantic/Interpreter-Qwen3-1.7B") model = AutoModelForCausalLM.from_pretrained("Ismantic/Interpreter-Qwen3-1.7B", torch_dtype=torch.bfloat16).cuda().eval() instr = ("Translate the following text from Chinese to English.\n" "Chinese: 人工智能正在深刻改变我们的生活方式。\nEnglish:") prompt = f"<|im_start|>user\n{instr}<|im_end|>\n<|im_start|>assistant\n" ids = tok(prompt, return_tensors="pt").to(model.device) out = model.generate(**ids, max_new_tokens=256, do_sample=False, eos_token_id=tok.convert_tokens_to_ids("<|im_end|>")) print(tok.decode(out[0][ids.input_ids.shape[1]:], skip_special_tokens=True).strip()) ``` vLLM works too — same ChatML prompt, `stop=["<|im_end|>"]`. For a quick interactive demo, grab `translate.py` from this repo and run `python translate.py` (needs `vllm`) — type sentences, zh↔en auto-detected. ## Training Three stages, all on a single RTX 4090: - **SFT** — full fine-tune on ~36.8K zh↔en pairs (ALMA + X-ALMA human parallel, WMT22/23 leakage removed), loss on the response only. - **CPO** — LoRA preference training, `-log σ(β·(logπ_w − logπ_l)) + λ·NLL(y_w)`, on ~44K **self-generated** preference pairs (5 candidates sampled from the SFT model, best/worst picked by COMET). LoRA only — full-parameter CPO collapses the model. - **GRPO** — full-parameter RL. Reward = reference-based `wmt22-comet-da` COMET (1.0) + a 4-gram repetition penalty (0.3), over WMT17–21 source prompts. Training code, data provenance and the negative results (what was tried and rejected, with numbers) are in the [Interpreter repo](https://github.com/Ismantic/Interpreter). ## License & attribution Apache-2.0, following the base model. Training data derives from the ALMA / X-ALMA parallel corpora and WMT news test sets. Please respect the licenses of those upstream models and datasets.