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.

Translation quality of PLaMo 3 Translate, TranslateGemma and HY-MT2

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.

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|>"
)
  • translation in dataset denotes the translation task. Because this model is dedicated to translation, always set dataset to translation.
  • The part following <|plamo:msg|> in input is the source text to translate.
  • <|plamo:key|>lang<|plamo:val|>en in output sets 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
57
Safetensors
Model size
9B params
Tensor type
BF16
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for pfnet/plamo-3-translate-8b

Quantizations
6 models

Collection including pfnet/plamo-3-translate-8b