Instructions to use pfnet/plamo-3-translate-8b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use pfnet/plamo-3-translate-8b with Transformers:
# Use a pipeline as a high-level helper # Warning: Pipeline type "translation" is no longer supported in transformers v5. # You must load the model directly (see below) or downgrade to v4.x with: # pip install "transformers<5.0.0" from transformers import pipeline pipe = pipeline("translation", model="pfnet/plamo-3-translate-8b", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("pfnet/plamo-3-translate-8b", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
PLaMo 3 Translate 8B
ๆฅๆฌ่ช็ใฎREADME / Japanese README
PLaMo 3 Translate 8B is a translation-specialized LLM developed by Preferred Networks (PFN) that delivers world-class translation quality. It is built on PLaMo 3 NICT, a pretrained model developed through joint research by PFN and the National Institute of Information and Communications Technology (NICT). We further trained this base model on tens of billions of tokens of translation-focused data. For development details, see the tech blog.
PLaMo 3 Translate 8B supports translation among 53 languages (see Supported Languages). It can also take surrounding context and a glossary into account, and lets you choose between plain and polite style for Japanese output. The maximum length during training was 32,768 tokens for the input and output combined. The model can translate long passages in one go, but split anything longer so that the input and output together stay within this limit.
PLaMo 3 Translate 8B is available under the PLaMo Community License. Personal use, such as learning or hobby projects, and other non-commercial use, including academic use, are free of charge with no prior registration. See License for the terms of commercial use.
Benchmarks
PLaMo 3 Translate delivers world-class quality in both JapaneseโEnglish and multilingual translation. Even the 2B model outperforms the translation-specialized LLMs we compared against on every metric in the figure below.
The top row shows JapaneseโEnglish translation quality as the average of PFTB, SaaS and WMT24++ COMET-22. The middle row shows translation between Japanese and 14 other languages, and the bottom row between English and 14 other languages, each as the average of FLORES+ chrF++ in both directions. Higher is better for all scores.
For the FLORES+ multilingual evaluation, we selected the following 15 of the 53 supported languages. Translation was evaluated in both directions between Japanese or English and each of the remaining 14 languages.
- Japanese, English, Arabic, Indonesian, Italian, Dutch, Korean, Spanish, Thai, Chinese (Simplified and Traditional), German, French, Vietnamese, Russian
For details, see the tech blog.
Choosing a Model
Model List
PLaMo 3 Translate comes in four sizes: 0.8B, 2B, 8B and 31B. For each size, quantized and converted variants are provided in separate repositories.
| Size | BF16 | FP8 | W4A16 | W4AFP8 | NVFP4 | GGUF | MLX |
|---|---|---|---|---|---|---|---|
| 0.8B | BF16 | FP8 | W4A16 | W4AFP8 | NVFP4 | GGUF | MLX-4bit |
| 2B | BF16 | FP8 | W4A16 | W4AFP8 | NVFP4 | GGUF | MLX-4bit |
| 8B | BF16 | FP8 | W4A16 | W4AFP8 | NVFP4 | GGUF | MLX-4bit |
| 31B | BF16 | FP8 | W4A16 | W4AFP8 | NVFP4 | GGUF | MLX-4bit |
Accuracy changes from quantization
For each model size, the tables compare the translation accuracy of BF16 with that of each distribution format. The value in parentheses under each score is the difference from BF16 of the same size (a negative value means lower accuracy). Higher is better for all scores.
For details on the evaluation metrics, see the tech blog.
Overall, GGUF Q2_K shows lower translation accuracy on some metrics, while the other formats stay close to BF16.
Size is the total size of the weight files.
31B
| Format | Size (GB) | PFTB (EnโJa) | SaaS (EnโJa) | WMT24++ COMET-22 (EnโJa) | FLORES+ chrF++ (JaโMultilingual) | FLORES+ chrF++ (EnโMultilingual) |
|---|---|---|---|---|---|---|
| BF16 | 63.51 | 0.6244 | 0.5786 | 0.8799 | 37.81 | 56.61 |
| FP8 | 32.31 | 0.6240 (-0.0004) |
0.5803 (+0.0017) |
0.8799 (0.0000) |
37.79 (-0.02) |
56.60 (-0.01) |
| W4A16 | 17.19 | 0.6258 (+0.0014) |
0.5777 (-0.0009) |
0.8805 (+0.0006) |
37.74 (-0.07) |
56.49 (-0.12) |
| W4AFP8 | 17.19 | 0.6223 (-0.0021) |
0.5716 (-0.0070) |
0.8813 (+0.0014) |
37.71 (-0.10) |
56.53 (-0.08) |
| NVFP4 | 18.66 | 0.6258 (+0.0014) |
0.5748 (-0.0038) |
0.8809 (+0.0010) |
37.70 (-0.11) |
56.49 (-0.12) |
| GGUF BF16 | 63.52 | 0.6241 (-0.0003) |
0.5793 (+0.0007) |
0.8799 (0.0000) |
37.82 (+0.01) |
56.59 (-0.02) |
| GGUF Q4_K_M | 19.53 | 0.6237 (-0.0007) |
0.5770 (-0.0016) |
0.8810 (+0.0011) |
37.84 (+0.03) |
56.55 (-0.06) |
| GGUF Q3_K_M | 15.86 | 0.6223 (-0.0021) |
0.5780 (-0.0006) |
0.8813 (+0.0014) |
37.78 (-0.03) |
56.54 (-0.07) |
| GGUF Q2_K | 12.61 | 0.6126 (-0.0118) |
0.5745 (-0.0041) |
0.8801 (+0.0002) |
37.36 (-0.45) |
56.16 (-0.45) |
| MLX 4bit | 18.66 | 0.6222 (-0.0022) |
0.5779 (-0.0007) |
0.8800 (+0.0001) |
37.82 (+0.01) |
56.58 (-0.03) |
8B
| Format | Size (GB) | PFTB (EnโJa) | SaaS (EnโJa) | WMT24++ COMET-22 (EnโJa) | FLORES+ chrF++ (JaโMultilingual) | FLORES+ chrF++ (EnโMultilingual) |
|---|---|---|---|---|---|---|
| BF16 | 17.06 | 0.6119 | 0.5750 | 0.8805 | 37.45 | 56.22 |
| FP8 | 9.41 | 0.6123 (+0.0004) |
0.5764 (+0.0014) |
0.8805 (0.0000) |
37.40 (-0.05) |
56.17 (-0.05) |
| W4A16 | 5.71 | 0.6114 (-0.0005) |
0.5749 (-0.0001) |
0.8789 (-0.0016) |
37.36 (-0.09) |
56.19 (-0.03) |
| W4AFP8 | 5.71 | 0.6174 (+0.0055) |
0.5759 (+0.0009) |
0.8794 (-0.0011) |
37.34 (-0.11) |
56.12 (-0.10) |
| NVFP4 | 6.07 | 0.6040 (-0.0079) |
0.5783 (+0.0033) |
0.8792 (-0.0013) |
37.26 (-0.19) |
56.10 (-0.12) |
| GGUF BF16 | 17.07 | 0.6110 (-0.0009) |
0.5755 (+0.0005) |
0.8802 (-0.0003) |
37.46 (+0.01) |
56.22 (0.00) |
| GGUF Q4_K_M | 5.28 | 0.6100 (-0.0019) |
0.5765 (+0.0015) |
0.8802 (-0.0003) |
37.39 (-0.06) |
56.18 (-0.04) |
| GGUF Q3_K_M | 4.31 | 0.6019 (-0.0100) |
0.5707 (-0.0043) |
0.8826 (+0.0021) |
37.20 (-0.25) |
55.93 (-0.29) |
| GGUF Q2_K | 3.45 | 0.5989 (-0.0130) |
0.5676 (-0.0074) |
0.8791 (-0.0014) |
36.54 (-0.91) |
55.31 (-0.91) |
| MLX 4bit | 6.07 | 0.6102 (-0.0017) |
0.5751 (+0.0001) |
0.8796 (-0.0009) |
37.41 (-0.04) |
56.19 (-0.03) |
2B
| Format | Size (GB) | PFTB (EnโJa) | SaaS (EnโJa) | WMT24++ COMET-22 (EnโJa) | FLORES+ chrF++ (JaโMultilingual) | FLORES+ chrF++ (EnโMultilingual) |
|---|---|---|---|---|---|---|
| BF16 | 5.76 | 0.6061 | 0.5612 | 0.8780 | 37.02 | 55.74 |
| FP8 | 3.43 | 0.6067 (+0.0006) |
0.5613 (+0.0001) |
0.8776 (-0.0004) |
36.98 (-0.04) |
55.76 (+0.02) |
| W4A16 | 2.30 | 0.6032 (-0.0029) |
0.5594 (-0.0018) |
0.8783 (+0.0003) |
36.96 (-0.06) |
55.69 (-0.05) |
| W4AFP8 | 2.30 | 0.6022 (-0.0039) |
0.5612 (0.0000) |
0.8772 (-0.0008) |
36.95 (-0.07) |
55.71 (-0.03) |
| NVFP4 | 2.41 | 0.6032 (-0.0029) |
0.5626 (+0.0014) |
0.8783 (+0.0003) |
36.82 (-0.20) |
55.64 (-0.10) |
| GGUF BF16 | 5.76 | 0.6062 (+0.0001) |
0.5619 (+0.0007) |
0.8782 (+0.0002) |
37.02 (0.00) |
55.75 (+0.01) |
| GGUF Q4_K_M | 1.81 | 0.6062 (+0.0001) |
0.5602 (-0.0010) |
0.8774 (-0.0006) |
37.00 (-0.02) |
55.76 (+0.02) |
| GGUF Q4_0 | 1.70 | 0.6069 (+0.0008) |
0.5604 (-0.0008) |
0.8791 (+0.0011) |
36.12 (-0.90) |
55.62 (-0.12) |
| GGUF Q3_K_M | 1.50 | 0.6053 (-0.0008) |
0.5644 (+0.0032) |
0.8789 (+0.0009) |
36.81 (-0.21) |
55.59 (-0.15) |
| GGUF Q2_K | 1.23 | 0.5977 (-0.0084) |
0.5610 (-0.0002) |
0.8777 (-0.0003) |
36.45 (-0.57) |
55.02 (-0.72) |
| MLX 4bit | 2.41 | 0.6040 (-0.0021) |
0.5624 (+0.0012) |
0.8777 (-0.0003) |
36.99 (-0.03) |
55.64 (-0.10) |
0.8B
| Format | Size (GB) | PFTB (EnโJa) | SaaS (EnโJa) | WMT24++ COMET-22 (EnโJa) | FLORES+ chrF++ (JaโMultilingual) | FLORES+ chrF++ (EnโMultilingual) |
|---|---|---|---|---|---|---|
| BF16 | 1.78 | 0.5862 | 0.5530 | 0.8724 | 36.08 | 54.44 |
| FP8 | 1.22 | 0.5846 (-0.0016) |
0.5491 (-0.0039) |
0.8726 (+0.0002) |
36.00 (-0.08) |
54.60 (+0.16) |
| W4A16 | 0.95 | 0.5847 (-0.0015) |
0.5439 (-0.0091) |
0.8711 (-0.0013) |
35.78 (-0.30) |
53.95 (-0.49) |
| W4AFP8 | 0.95 | 0.5783 (-0.0079) |
0.5456 (-0.0074) |
0.8718 (-0.0006) |
35.75 (-0.33) |
54.38 (-0.06) |
| NVFP4 | 0.98 | 0.5787 (-0.0075) |
0.5436 (-0.0094) |
0.8702 (-0.0022) |
35.54 (-0.54) |
54.20 (-0.24) |
| GGUF BF16 | 1.78 | 0.5873 (+0.0011) |
0.5533 (+0.0003) |
0.8727 (+0.0003) |
36.10 (+0.02) |
54.45 (+0.01) |
| GGUF Q4_K_M | 0.57 | 0.5832 (-0.0030) |
0.5451 (-0.0079) |
0.8716 (-0.0008) |
35.90 (-0.18) |
54.47 (+0.03) |
| GGUF Q4_0 | 0.55 | 0.5853 (-0.0009) |
0.5500 (-0.0030) |
0.8723 (-0.0001) |
34.97 (-1.11) |
54.11 (-0.33) |
| GGUF Q3_K_M | 0.49 | 0.5798 (-0.0064) |
0.5520 (-0.0010) |
0.8710 (-0.0014) |
35.32 (-0.76) |
54.15 (-0.29) |
| GGUF Q2_K | 0.41 | 0.5620 (-0.0242) |
0.5397 (-0.0133) |
0.8659 (-0.0065) |
33.56 (-2.52) |
51.15 (-3.29) |
| MLX 4bit | 0.98 | 0.5773 (-0.0089) |
0.5476 (-0.0054) |
0.8724 (0.0000) |
35.82 (-0.26) |
54.41 (-0.03) |
Choosing a Distribution Format
Each size of PLaMo 3 Translate is available in the following distribution formats, depending on your use case and hardware.
| Format | Target hardware | Inference engine | Typical use |
|---|---|---|---|
| BF16 | GPUs with BF16 support | Transformers / vLLM | Prioritizes accuracy with no quantization, when memory allows |
| FP8 | NVIDIA Ada Lovelace / Hopper / Blackwell | vLLM | Balances accuracy with memory savings and speed |
| W4A16 | NVIDIA Ampere or later | vLLM | 4-bit weights to run with less GPU memory |
| W4AFP8 | NVIDIA Hopper | vLLM | 4-bit weights with FP8 compute, aiming at both low memory and high throughput |
| NVFP4 | NVIDIA Blackwell | vLLM | FP4 compute, aiming at low memory and high speed |
| GGUF | CPU / various GPUs | llama.cpp | Runs on a local PC, optionally combining CPU and GPU |
| MLX-4bit | Apple silicon | mlx-lm | Memory-efficient inference on a Mac |
Usage
Transformers
Download the model files and move into that directory. Run the following examples in this directory.
pip install -U huggingface_hub
hf download pfnet/plamo-3-translate-8b --local-dir plamo-3-translate-8b
cd plamo-3-translate-8b
Install the required packages.
pip install -U torch transformers accelerate numba
Translating a single text
A chat template is provided so you can try translation easily. Given the source text and the target language, it builds a prompt in the PFML3 format.
For production use, such as integrating the model into an application, we recommend building the prompt directly in the PFML3 format and passing it to the vLLM Completions API.
The following example translates Japanese into English.
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(".", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
".", trust_remote_code=True, dtype="bfloat16", device_map="auto",
)
inputs = tokenizer.apply_chat_template(
[{"role": "user", "content": "ไผ่ญฐใฏๆฅ้ฑใฎๆๆๆฅใซๅคๆดใใใพใใใ"}],
target_lang="en",
add_generation_prompt=True,
return_dict=True, return_tensors="pt",
).to(model.device)
output = model.generate(**inputs, do_sample=False, max_new_tokens=512)
text = tokenizer.decode(output[0, inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(text)
max_new_tokens is the generation limit for the translation. This example sets it to 512 tokens. When translating long text, adjust the limit so that the whole input (source text, history, context, glossary and so on) plus the output fits within the limit of your runtime.
Example output:
The meeting has been rescheduled for next Monday.
The example above does not specify the source language. When source_lang is omitted, the model detects the language from the source text. To specify it explicitly, pass source_lang="ja", for example.
Translating multiple texts at once
Multiple texts can be translated in a batch by passing them to the chat template together. The following example uses the model and tokenizer loaded above to translate two texts into English.
tokenizer.padding_side = "left"
texts = [
"ไผ่ญฐใฏๆฅ้ฑใฎๆๆๆฅใซๅคๆดใใใพใใใ",
"ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใฆใใ ใใใ",
]
messages = [[{"role": "user", "content": text}] for text in texts]
inputs = tokenizer.apply_chat_template(
messages,
target_lang="en",
add_generation_prompt=True,
padding=True,
return_dict=True, return_tensors="pt",
).to(model.device)
outputs = model.generate(**inputs, do_sample=False, max_new_tokens=512)
translations = tokenizer.batch_decode(
outputs[:, inputs["input_ids"].shape[1]:], skip_special_tokens=True,
)
for source, translation in zip(texts, translations):
print(f"{source} โ {translation}")
The inputs are padded on the left to equalize their lengths, and only the generated translations are extracted. Translation options such as target_lang apply to every text in the batch in this example.
Continuing a translation with previous translations
When translating a document paragraph by paragraph, you can pass the previous sourceโtranslation pairs as history. This lets the model follow the earlier word choices and style when translating the next passage.
With the chat template, alternate the source text as user and its translation as assistant, and put the current source text in the final user message. History is not stored automatically, so include the pairs you need in each request.
The translation direction is shared by the whole request: source_lang applies to every source text and target_lang to every translation.
History also counts toward the input tokens. Keep the whole input plus the generated translation within 32,768 tokens and within the limit of your runtime. As the history grows, we recommend dropping the oldest sourceโtranslation pairs first and keeping the most recent ones.
This example uses the model and tokenizer loaded above.
messages = [
{"role": "user", "content": "ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใพใใ"},
{"role": "assistant", "content": "Open the project dashboard."},
{"role": "user", "content": "้ฒ่กไธญใฎใฟในใฏใใในใฆ่กจ็คบใใใพใใ"},
{"role": "assistant", "content": "It lists all active tasks."},
{"role": "user", "content": "ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ"},
]
inputs = tokenizer.apply_chat_template(
messages, source_lang="ja", target_lang="en",
add_generation_prompt=True,
return_dict=True, return_tensors="pt",
).to(model.device)
output = model.generate(**inputs, do_sample=False, max_new_tokens=512)
text = tokenizer.decode(output[0, inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(text)
PFML3 Prompt Format
PFML3 is PLaMo's prompt format, in which the text to translate, the target language and other elements are delimited by special tokens. In the Transformers examples above, the chat template converts the source text and target language into PFML3. This section explains how to read the converted prompt and how to write prompts by hand.
For production use, we recommend building the prompt directly in PFML3 and passing it to the vLLM Completions API.
Converting the Transformers example above into PFML3 gives the following. The beginning-of-sequence token is omitted here, and the Python string is split across lines for readability. The actual prompt contains no line breaks.
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input"
"<|plamo:msg|>ไผ่ญฐใฏๆฅ้ฑใฎๆๆๆฅใซๅคๆดใใใพใใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
translationindatasetdenotes the translation task. Because this model is dedicated to translation, always setdatasettotranslation.- The part following
<|plamo:msg|>ininputis the source text to translate. <|plamo:key|>lang<|plamo:val|>eninoutputsets the target language to English. The translation is generated right after the final<|plamo:msg|>.
<|plamo:tag|> marks the start of each element, and <|plamo:msg|> marks the start of its body. To specify attributes such as the language or style, write the attribute name after <|plamo:key|> and its value after <|plamo:val|>, following the element name. For example, adding <|plamo:key|>form<|plamo:val|>plain to output requests plain style.
Context and a glossary are optional. To use them, add context and then glossary, in that order, between dataset and input. When translation history is also used, put context right after dataset, list the previous input/output pairs, and put glossary immediately before the current input. In the glossary, write a source term after <|plamo:index|> and its translation after <|plamo:item|>, repeating this pair for each term. See Translation Options for concrete examples.
Using a handwritten prompt
When writing PFML3 by hand, start by setting dataset to translation and end the output element with <|plamo:msg|>. After generating the translation, the model emits <|plamo:tag|> or <|plamo:bos|> and stops.
The handwritten examples above omit <|plamo:bos|>, which marks the beginning of the sequence. The Transformers tokenizer, llama.cpp and mlx-lm add the beginning-of-sequence token automatically. With the vLLM Completions API, specify add_special_tokens=true.
A string produced by the chat template already contains the beginning-of-sequence token. If you pass a string obtained with tokenize=False to the Transformers tokenizer, specify add_special_tokens=False to avoid adding it twice.
For example, to pass a handwritten prompt to Transformers, use the model and tokenizer from the Transformers example above.
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
output = model.generate(**inputs, do_sample=False, max_new_tokens=512)
text = tokenizer.decode(output[0, inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(text)
Specifying translation history in PFML3
Translation history can also be written in PFML3 by hand. List the already translated input and output elements in document order, then add the current source text followed by an output element with an empty body. In the following example, only the last sentence, "ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ", is translated, with reference to the two previous pairs.
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>Open the project dashboard."
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>้ฒ่กไธญใฎใฟในใฏใใในใฆ่กจ็คบใใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>It lists all active tasks."
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
Run the example in "Using a handwritten prompt" above with prompt replaced by this string.
To continue translating, append the current source text and the generated translation to the history as a pair. Then add an input element containing the next source text and an output element with an empty body.
Keep only the body of each translation in the history. The translation returned by the example above can be used as is.
If <|plamo:tag|> or <|plamo:bos|> remains at the end of a translation, remove it so that exactly one <|plamo:tag|> separates it from the next input.
Translation Options
Specify the target language, style, context, glossary and other options as arguments to apply_chat_template(), not in a system message or in the source text.
Run the Transformers example above with the part that builds inputs replaced by the following code.
| Argument | Description |
|---|---|
target_lang |
Language code of the target language. Required. |
source_lang |
Language code of the source text. Optional. |
context |
Reference context for interpreting the source text, such as the surrounding text or the situation. |
glossary |
A list of {"source": "source term", "target": "translation"} dictionaries, one per term. |
form |
plain for plain style or polite for polite style (only with target_lang="ja"). |
When combined with translation history, context is passed as reference context for the whole request, while glossary and form apply to the current translation. Previous translations themselves are not changed.
Specifying terms with a glossary
Pass pairs of source terms and their translations in glossary to control how the terms are translated.
inputs = tokenizer.apply_chat_template(
[{"role": "user", "content": "ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใฆใใ ใใใ"}],
target_lang="en",
glossary=[
{"source": "็ฎก็็ป้ข", "target": "dashboard"},
{"source": "ใใญใธใงใฏใ", "target": "project"},
],
add_generation_prompt=True,
return_dict=True, return_tensors="pt",
).to(model.device)
Example output:
Please open the project dashboard.
PFML3 prompt for this example
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>glossary"
"<|plamo:index|>็ฎก็็ป้ข<|plamo:item|>dashboard"
"<|plamo:index|>ใใญใธใงใฏใ<|plamo:item|>project"
"<|plamo:tag|>input<|plamo:msg|>ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใฆใใ ใใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
Providing context
Use context to pass the surrounding text or to describe the situation. In this example, the source text ใใฟใๅใใพใใใ is ambiguous because ใใฟ can mean either hair or paper. The context says that the speaker is making origami, so it is translated as paper.
inputs = tokenizer.apply_chat_template(
[{"role": "user", "content": "ใใฟใๅใใพใใใ"}],
target_lang="en",
context="ๅทฅไฝใงๆใ็ดใไฝใฃใฆใใพใใ",
add_generation_prompt=True,
return_dict=True, return_tensors="pt",
).to(model.device)
Example output:
I cut the paper.
PFML3 prompt for this example
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>context"
"<|plamo:msg|>ๅทฅไฝใงๆใ็ดใไฝใฃใฆใใพใใ"
"<|plamo:tag|>input<|plamo:msg|>ใใฟใๅใใพใใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
Specifying plain or polite style
When translating into Japanese, form="plain" requests the plain style (da/dearu) and form="polite" requests the polite style (desu/masu). Because form applies only to Japanese translations, this example translates English into Japanese.
inputs = tokenizer.apply_chat_template(
[{"role": "user", "content": "This system is convenient."}],
target_lang="ja",
form="plain",
add_generation_prompt=True,
return_dict=True, return_tensors="pt",
).to(model.device)
Example outputs for the same source text:
| Style | Option | Translation |
|---|---|---|
| Plain | form="plain" |
ใใฎใทในใใ ใฏไพฟๅฉใ ใ |
| Polite | form="polite" |
ใใฎใทในใใ ใฏไพฟๅฉใงใใ |
PFML3 prompt for this example
Plain:
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input<|plamo:msg|>This system is convenient."
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>ja"
"<|plamo:key|>form<|plamo:val|>plain<|plamo:msg|>"
)
Polite:
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input<|plamo:msg|>This system is convenient."
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>ja"
"<|plamo:key|>form<|plamo:val|>polite<|plamo:msg|>"
)
Specifying all options at once
Translation history, context, a glossary and the style can be combined in one request. The following example translates the third sentence after two previous pairs, passing the page type as context and fixing the translation of ใชใผใใผ with the glossary. context is passed as reference context for the whole request, and glossary applies to the current translation. When translating into Japanese, form can be added in the same way.
inputs = tokenizer.apply_chat_template(
[
{"role": "user", "content": "ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใพใใ"},
{"role": "assistant", "content": "Open the project dashboard."},
{"role": "user", "content": "้ฒ่กไธญใฎใฟในใฏใใในใฆ่กจ็คบใใใพใใ"},
{"role": "assistant", "content": "It lists all active tasks."},
{"role": "user", "content": "ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ"},
],
source_lang="ja", target_lang="en",
context="ใใญใธใงใฏใ็ฎก็ใใผใซใฎใใซใใใผใธใงใใ",
glossary=[{"source": "ใชใผใใผ", "target": "assignee"}],
add_generation_prompt=True,
return_dict=True, return_tensors="pt",
).to(model.device)
Example output:
You can also filter by assignee.
PFML3 prompt for this example
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>context<|plamo:msg|>ใใญใธใงใฏใ็ฎก็ใใผใซใฎใใซใใใผใธใงใใ"
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>Open the project dashboard."
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>้ฒ่กไธญใฎใฟในใฏใใในใฆ่กจ็คบใใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>It lists all active tasks."
"<|plamo:tag|>glossary<|plamo:index|>ใชใผใใผ<|plamo:item|>assignee"
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
vLLM
Starting the server
Download the model files and move into that directory. Skip this step if you have already downloaded them by following the Transformers instructions.
pip install -U huggingface_hub
hf download pfnet/plamo-3-translate-8b --local-dir plamo-3-translate-8b
cd plamo-3-translate-8b
Install the required packages and start the vLLM server.
pip install -U vllm openai numba
vllm serve . --trust-remote-code \
--served-model-name plamo-3-translate \
--max-model-len 16384 --max-num-seqs 4
This example sets the maximum combined length of the input and output to 16,384 tokens. Adjust it to fit the available GPU memory as needed.
Translating with the Chat Completions API
With the Chat Completions API, put the current source text in the last user message and pass the translation options in chat_template_kwargs.
curl http://localhost:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "plamo-3-translate",
"messages": [{"role": "user", "content": "ใใใซใกใฏใ"}],
"chat_template_kwargs": {"source_lang": "ja", "target_lang": "en"},
"temperature": 0,
"max_tokens": 512,
"stop": ["<|plamo:tag|>", "<|plamo:bos|>"]
}'
max_tokens is the generation limit for the translation. This example sets it to 512 tokens. When translating long text, adjust the limit so that the whole input (source text, history, context, glossary and so on) plus the output fits within the limit of your runtime.
The translation is returned in choices[0].message.content.
Translating multiple texts at once
To translate multiple texts, send one request per text and run the requests in parallel. vLLM batches the requests it receives.
from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
texts = [
"ไผ่ญฐใฏๆฅ้ฑใฎๆๆๆฅใซๅคๆดใใใพใใใ",
"ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใฆใใ ใใใ",
]
def translate(text):
response = client.chat.completions.create(
model="plamo-3-translate",
messages=[{"role": "user", "content": text}],
temperature=0,
max_tokens=512,
stop=["<|plamo:tag|>", "<|plamo:bos|>"],
extra_body={"chat_template_kwargs": {"target_lang": "en"}},
)
return response.choices[0].message.content
with ThreadPoolExecutor(max_workers=4) as executor:
translations = list(executor.map(translate, texts))
for source, translation in zip(texts, translations):
print(f"{source} โ {translation}")
Translating with history via the Chat Completions API
Pass the already translated sourceโtranslation pairs as user/assistant pairs. Only the last user message is translated.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
messages = [
{"role": "user", "content": "ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใพใใ"},
{"role": "assistant", "content": "Open the project dashboard."},
{"role": "user", "content": "้ฒ่กไธญใฎใฟในใฏใใในใฆ่กจ็คบใใใพใใ"},
{"role": "assistant", "content": "It lists all active tasks."},
{"role": "user", "content": "ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ"},
]
response = client.chat.completions.create(
model="plamo-3-translate",
messages=messages,
temperature=0,
max_tokens=512,
stop=["<|plamo:tag|>", "<|plamo:bos|>"],
extra_body={"chat_template_kwargs": {"source_lang": "ja", "target_lang": "en"}},
)
print(response.choices[0].message.content)
Translating with the Completions API
Pass one of the PFML3 prompts shown in the translation examples as prompt.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input"
"<|plamo:msg|>ไผ่ญฐใฏๆฅ้ฑใฎๆๆๆฅใซๅคๆดใใใพใใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
response = client.completions.create(
model="plamo-3-translate",
prompt=prompt,
temperature=0,
max_tokens=512,
stop=["<|plamo:tag|>", "<|plamo:bos|>"],
extra_body={"add_special_tokens": True},
)
print(response.choices[0].text)
The translation is returned in choices[0].text.
Translating multiple texts at once
When using PFML3 prompts directly, you can likewise send one request per text in parallel.
from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
texts = [
"ไผ่ญฐใฏๆฅ้ฑใฎๆๆๆฅใซๅคๆดใใใพใใใ",
"ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใฆใใ ใใใ",
]
def translate(text):
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input<|plamo:msg|>"
f"{text}"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
response = client.completions.create(
model="plamo-3-translate",
prompt=prompt,
temperature=0,
max_tokens=512,
stop=["<|plamo:tag|>", "<|plamo:bos|>"],
extra_body={"add_special_tokens": True},
)
return response.choices[0].text
with ThreadPoolExecutor(max_workers=4) as executor:
translations = list(executor.map(translate, texts))
for source, translation in zip(texts, translations):
print(f"{source} โ {translation}")
Continuing a translation with history
Translation with history also works with the Completions API. Pass a PFML3 prompt that includes the already translated sourceโtranslation pairs, and the translation of the last source text is returned.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
prompt = (
"<|plamo:tag|>dataset<|plamo:msg|>translation"
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>ใใญใธใงใฏใใฎ็ฎก็็ป้ขใ้ใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>Open the project dashboard."
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>้ฒ่กไธญใฎใฟในใฏใใในใฆ่กจ็คบใใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>It lists all active tasks."
"<|plamo:tag|>input<|plamo:key|>lang<|plamo:val|>ja<|plamo:msg|>ใชใผใใผใงใใฃใซใฟใชใณใฐใใใใจใใงใใพใใ"
"<|plamo:tag|>output<|plamo:key|>lang<|plamo:val|>en<|plamo:msg|>"
)
response = client.completions.create(
model="plamo-3-translate",
prompt=prompt,
temperature=0,
max_tokens=512,
stop=["<|plamo:tag|>", "<|plamo:bos|>"],
extra_body={"add_special_tokens": True},
)
print(response.choices[0].text)
Supported Languages
53 languages are supported, including Japanese and English. Simplified and Traditional Chinese are counted as separate languages. Because Hugging Face groups Chinese as a single language in its language display, the model page shows 52 languages.
Supported languages and language codes
| Language | Code | Language | Code |
|---|---|---|---|
| Japanese | ja |
English | en |
| Chinese (Simplified) | zh-hans |
Chinese (Traditional) | zh-hant |
| Korean | ko |
Arabic | ar |
| Azerbaijani | az |
Belarusian | be |
| Bulgarian | bg |
Bengali | bn |
| Catalan | ca |
Cebuano | ceb |
| German | de |
Spanish | es |
| Estonian | et |
Basque | eu |
| Persian | fa |
French | fr |
| Gujarati | gu |
Hebrew | he |
| Hindi | hi |
Croatian | hr |
| Hungarian | hu |
Armenian | hy |
| Indonesian | id |
Italian | it |
| Javanese | jv |
Georgian | ka |
| Kazakh | kk |
Khmer | km |
| Lithuanian | lt |
Latvian | lv |
| Malayalam | ml |
Marathi | mr |
| Malay | ms |
Burmese | my |
| Nepali | ne |
Dutch | nl |
| Punjabi | pa |
Polish | pl |
| Russian | ru |
Sinhala | si |
| Slovak | sk |
Slovenian | sl |
| Serbian | sr |
Swahili | sw |
| Tamil | ta |
Telugu | te |
| Thai | th |
Tagalog | tl |
| Urdu | ur |
Uzbek | uz |
| Vietnamese | vi |
License
PLaMo 3 Translate 8B is released under the PLaMo Community License.
Personal and non-commercial use
For personal use, such as learning or hobby projects, you can download and use the model free of charge. Non-commercial use, including academic use, is also free, with no restriction based on revenue or sales and no prior registration with PFN.
Commercial use when revenue or sales is 1 billion yen or less
If the revenue or sales of the user or its affiliates in the most recent fiscal year is 1 billion yen or less, register your intended use through the PLaMo Commercial Use Registration Form. Commercial use is free of charge from the moment you submit the form.
Commercial use when revenue or sales exceeds 1 billion yen
A separate license agreement is required. Instead of the registration form above, please contact PFN through the PLaMo Translation Model inquiry page.
See the full text of the PLaMo Community License for details.
Preferred Networks Group AI Policy
- Downloads last month
- 89
