Instructions to use ProprietaryLegal/Qwen3.8-27B-CJK-Trim with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ProprietaryLegal/Qwen3.8-27B-CJK-Trim with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="ProprietaryLegal/Qwen3.8-27B-CJK-Trim") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("ProprietaryLegal/Qwen3.8-27B-CJK-Trim") model = AutoModelForMultimodalLM.from_pretrained("ProprietaryLegal/Qwen3.8-27B-CJK-Trim", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use ProprietaryLegal/Qwen3.8-27B-CJK-Trim with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "ProprietaryLegal/Qwen3.8-27B-CJK-Trim" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ProprietaryLegal/Qwen3.8-27B-CJK-Trim", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/ProprietaryLegal/Qwen3.8-27B-CJK-Trim
- SGLang
How to use ProprietaryLegal/Qwen3.8-27B-CJK-Trim with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "ProprietaryLegal/Qwen3.8-27B-CJK-Trim" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ProprietaryLegal/Qwen3.8-27B-CJK-Trim", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "ProprietaryLegal/Qwen3.8-27B-CJK-Trim" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ProprietaryLegal/Qwen3.8-27B-CJK-Trim", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use ProprietaryLegal/Qwen3.8-27B-CJK-Trim with Docker Model Runner:
docker model run hf.co/ProprietaryLegal/Qwen3.8-27B-CJK-Trim
Qwen3.8-27B-CJK-Trim
Qwen/Qwen3.8-27B with its Chinese, Japanese and Korean vocabulary removed. Nothing else is changed. Released by PLI Labs (ProprietaryLegal).
- Vocabulary: 248,077 → 181,544 real entries (padded table 248,320 → 181,760 rows). 66,533 CJK entries removed.
- Parameters: 27.357B → 26.675B (−681M parameters, −1.36 GB in BF16).
- No training of any kind. All 64 transformer layers, the vision tower and every other non-vocabulary tensor are bit-identical to the base (1,197 / 1,197 tensors). Only the rows of the input embedding (
embed_tokens) and output head (lm_head) belonging to removed entries were deleted, and the remaining rows were renumbered. - For English, it is the same model. Logits on held-out English legal text are bit-identical to the base, and greedy generations are token-for-token identical.
- It no longer drifts into CJK. No stray Chinese characters appear in English output. Asked a question in Chinese, it answers in English.
- Full vision-language model (Qwen3VLProcessor), BF16 safetensors, same chat template, thinking and tool tokens.
Why
We use Qwen3.8-27B for English-language legal drafting. In that setting the CJK part of the vocabulary does no useful work, and sometimes does harm: the base model occasionally emits a stray Chinese character mid-sentence in English output. Removing those entries:
- makes stray CJK output impossible through the normal vocabulary;
- shrinks both vocabulary tables by 27%, which saves memory and a little output-head compute on every token;
- is the first step of a planned domain-vocabulary experiment (see "What this release is not").
It is a subtractive, verifiable change, so it can be proven not to alter English behaviour.
What was removed and what was kept
An entry was removed when any text containing its bytes must contain a CJK code point. That covers:
- entries holding a complete CJK character;
- byte fragments whose leading or trailing partial UTF-8 sequence can only complete to a CJK character. This was checked by exhaustive enumeration over all code points.
| Removed | Entries |
|---|---|
| Han (Chinese characters, incl. Japanese kanji) | 54,715 |
| Hangul (Korean) | 6,807 |
| Hiragana | 2,487 |
| Katakana | 1,678 |
| CJK and fullwidth punctuation/forms | ~250 |
| Byte fragments that can only complete to CJK | 601 |
| Total | 66,533 |
The CJK script set covers Hangul Jamo, CJK radicals, ideographic description characters, CJK symbols and punctuation, kana, Bopomofo, enclosed CJK letters, CJK compatibility, CJK Unified Ideographs with extensions A–H, compatibility ideographs and forms, and halfwidth/fullwidth forms.
Kept, deliberately:
- all 256 single-byte entries, so any UTF-8 text can still be encoded;
- every special, control, chat, thinking, tool, image, video and vision token;
§,¶, curly quotes, en/em dashes, accented Latin letters, Greek, math symbols and digits. ASCII-only trims lose these, and they matter in legal text;- Cyrillic, Arabic, Hebrew, Thai, Indic and every other non-CJK script.
A broader trim that also removed the other non-Latin scripts would have dropped 103,447 entries (2.12 GB) and changed the tokenization of none of our English test documents. We chose not to do it, so the model keeps its other languages.
Dependency closure: the tokenizer is byte-level BPE, so a kept entry can depend on a merge that passes through a removed one. We checked every retained merge. None needed a removed entry: 0 entries had to be restored and there were 0 closure errors. The merge list is rebuilt without the removed merges, and no library helper that renumbers IDs was used.
How it was made
All work ran on one NVIDIA DGX Spark (GB10), using torch 2.11.0+cu130, transformers 5.18.0 and tokenizers 0.23.2. The base is Qwen/Qwen3.8-27B at revision 1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0. All 19 files were checked against their SHA-256 hashes before and after; the base was only read.
- Tokenizer surgery. The removal set was classified from the decoded byte-level vocabulary. The removed entries and their merges were deleted, and the kept entries were renumbered in their original order.
tokenizer.json,vocab.json,merges.txtandtokenizer_config.json(includingadded_tokens_decoder) were rewritten. - ID remap.
remap/id-remap.jsonholds the fullnew_to_oldmap for all 181,760 rows. The 216 padding rows are the base's own padding rows. - Checkpoint export (streaming). 16 of the 18 safetensors shards are byte-for-byte copies. The two shards holding
model.language_model.embed_tokens.weightandlm_head.weight(both[181760, 5120]; the tables are untied) were rewritten with the kept rows in new-ID order. - Config rebuild.
vocab_sizeand every special ID were updated inconfig.jsonandgeneration_config.json: bos, eos, pad, image, video, and vision start and end. Exactly 7 config keys differ from the base, all expected. Each special ID still resolves to the same token string as in the base, and the chat template's token IDs map exactly. - Streaming proof. Every non-vocabulary tensor was compared bit for bit with the base: 1,197 / 1,197 are identical. Both vocabulary tables were checked to equal the base row for row under the remap.
AutoProcessorloads, and the processor's image and video token IDs are correct.
The surgery, export and proof code is in trim-code/ (tokenizer_surgery.py, export_trim.py, prove_trim.py). provenance.json records the base revision, the tokenizer hash and the SHA-256 of every shard.
Evaluation (inference only)
The test text was a private corpus of about 3,500 English legal documents: pleadings, motions, affidavits, orders, agreements and correspondence, plus treatise and statute text. It is not released.
| Check | Result |
|---|---|
| Tokenization of English legal text | 3,526 / 3,526 documents tokenize identically after the remap |
| Byte-exact decode round trips | 3,540 / 3,540 |
| Logits vs. base (32 held-out excerpts, ≤384 tokens each) | bit-identical: max abs difference 0.0, KL 0.0 |
| Greedy generations vs. base (24 English prompts) | 24 / 24 token-for-token identical |
| CJK characters in English output | 0 |
| Chinese-language prompts | Base answered in Chinese; the trimmed model answered in English with 0 CJK characters |
§, ¶, curly quotes, dashes, accented names |
Intact |
| Base model's probability mass on the removed entries, on held-out English legal text | mean 0.03%, max 5.7% (now unavailable) |
| Load time / memory on DGX Spark | 70.9 s / 50.9 GB (base 74.3 s / 52.2 GB) |
The logits are bit-identical because the removed rows only ever competed in the output softmax. On text where the base never chose them, every remaining logit is computed by exactly the same weights.
Usage
The interface is the same as the base model's:
from transformers import AutoProcessor, AutoModelForImageTextToText
model_id = "ProprietaryLegal/Qwen3.8-27B-CJK-Trim"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForImageTextToText.from_pretrained(model_id, dtype="bfloat16", device_map="auto")
messages = [{"role": "user", "content": [{"type": "text", "text": "Explain what a pendente lite order is."}]}]
inputs = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True,
return_dict=True, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=512)
print(processor.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
We tested it with transformers 5.18. vLLM, llama.cpp and other runtimes should work, because the architecture is unchanged and only vocab_size differs, but we have not tested them yet.
Limitations and compatibility
- Chinese, Japanese and Korean are gone from the vocabulary. CJK input still encodes, through single-byte entries at about 3 tokens per character, but the model reads such text poorly and answers in English. Do not use this model for any CJK-language task.
- Token IDs differ from the base. Use only the tokenizer shipped in this repo. Any cached token IDs, logit-bias tables or stop-token ID lists built for the base must be remapped with
remap/id-remap.json. - Adapters and derived copies:
- LoRA adapters trained on the base that do not touch
embed_tokensorlm_headapply unchanged, because every other weight is identical. Adapters that do touch them need their rows remapped. - Quantized copies (GGUF, AWQ, NVFP4 and the like) must be made from this checkpoint, not converted from a base quant.
- LoRA adapters trained on the base that do not touch
- The size and speed gain is modest: about 2.5% of parameters, and slightly less output-head work per token. The main benefit is the guarantee against stray CJK output.
What this release is not
- Not fine-tuned. No training, distillation or data of any kind went into it. It is a structural subset of the base weights.
- Not a legal-domain model. Its legal knowledge and style are exactly the base model's.
- No new vocabulary added. A separate, unreleased experiment recycles never-reachable vocabulary slots for legal-English word pieces. Nothing from that experiment is in this repository.
Prior work
- Elsephire/Qwen3.6-27B-vocabulary-trimming: CJK and other non-Latin trimming of Qwen3.6-27B. We checked for the defects reported with that approach (stale
generation_config,added_tokens, image ID,vocab.json,merges.txt); none is present here. - bsaleh03/Qwen3.8-27B-ASCII-Condensed: ASCII-only trim of the same base, in GGUF. This release keeps non-ASCII legal punctuation and accented Latin letters, and ships full-precision safetensors with vision.
- KaihuaTang/Qwen-Tokenizer-Pruner.
- Teaching Old Tokenizers New Words (arXiv 2512.03989): structure-aware BPE pruning.
License
Apache 2.0, inherited from Qwen/Qwen3.8-27B. The original LICENSE file is included unchanged. All credit for the model itself belongs to the Qwen team.
- Downloads last month
- 31
Model tree for ProprietaryLegal/Qwen3.8-27B-CJK-Trim
Base model
Qwen/Qwen3.8-27B