PLaMo 3 Translate Brings Reviewable AI Translation to Bioconductor R Lessons
Translating a technical lesson is mostly about keeping the code intact. Bioconductor's maintainers learned that the hard way. Their Crowdin pipeline required converting executable R Markdown files, syncing translations back into the lessons, and rebuilding everything by hand. The new workflow moves AI-assisted translation into the lesson repositories themselves. Code and lesson markup are shielded from the model, and community review happens on GitHub rather than in a separate translation platform. Crowdin's support over the years was appreciated, but this setup fits how the lessons are actually built.
The first lesson through the pipeline is Introduction to data analysis with R and Bioconductor. Published editions now exist in Japanese, Spanish, Simplified Chinese, French and Urdu, and all five are open for community review and improvement.
What's under the hood: PLaMo 3 Translate
PLaMo 3 Translate is a family of large language models from Preferred Networks (PFN), built specifically for translation. PFN trains the models on source and translation pairs, then refines them so they prefer better translations. The smaller models learn from the 31B model through distillation. The family covers 53 languages and can take surrounding context and a glossary into account.
Those last two features matter most for lessons. A translation of a single sentence often depends on the explanation around it, and a term like "data frame" has to land the same way across every episode. Being able to pass nearby text and preferred terminology into the model is what makes passage-level translation workable for teaching material.
The models come in four sizes: 0.8B, 2B, 8B and 31B parameters. The Bioconductor workflow uses pfnet/plamo-3-translate-8b-MLX-4bit, the 8B model in a 4-bit MLX format. That quantization cuts memory use enough for local generation on Apple silicon Macs. The weights ship under the PLaMo Community License, and PFN's PLaMo 3 Translate: World-Class Translation with Open Weights—Here's How We Built It covers the training process and the weight release.
Five editions, and one language left out
The introductory lesson covers organising data in spreadsheets, using R and RStudio, manipulating data with dplyr, and visualising data. Each edition has two entry points: a lesson website for learners and a repository for contributors.
| Language | Read the lesson | Contribute on GitHub |
|---|---|---|
| Japanese | Japanese lesson | bioc-intro-plamo3translate-ja |
| Spanish | Spanish lesson | bioc-intro-plamo3translate-es |
| Simplified Chinese | Simplified Chinese lesson | bioc-intro-plamo3translate-zh-hans |
| French | French lesson | bioc-intro-plamo3translate-fr |
| Urdu | Urdu lesson | bioc-intro-plamo3translate-ur |
Portuguese is the notable absence. The project's Crowdin workspace received Portuguese contributions, and the maintainers are grateful for them. The PLaMo model in use doesn't support Portuguese, though, and it isn't on the supported-language list. That's a model limitation, not a judgment about the contributors' work, and it's the main reason the Portuguese edition isn't part of this release.
Coverage is still unfinished. Some setup pages and interface labels remain in English. The Urdu episodes are published, but that repository's updater configuration and translation guide still point to Japanese. Anyone who wants to regenerate Urdu text will need to adapt those files first.
How the translation pipeline works
The process runs in four steps, and the design choice I'd point to first is that the model never touches code.
- Read an English source revision. The translator reads the upstream lesson's R Markdown files from a Git revision, without checking that revision out over the translated working files.
- Reuse matching translations. Each translation repository stores its translation memory in
translation/seed-cache.json. The file holds previous translations and review statuses, keyed by source passage and episode. Matching records get reused. New or changed prose goes to the model. - Guide terminology and protect structure. A language-specific glossary and contextual guidance help the model disambiguate terms. Code blocks, inline code, link destinations and lesson markup are protected during translation, and structural checks run before any lesson file is replaced.
- Review and build. Maintainers inspect the translated text and the memory changes, build the lesson, and commit the reviewed result. The translator itself never commits or pushes.
Terminology lives in glossary.json
Each repository keeps its preferred terms in translation/glossary.json. The Japanese file, for instance, maps "data frame" to "データフレーム" and leaves "Bioconductor" unchanged. The translator passes those pairs to the model so terminology stays consistent across episodes.
Contributors can propose glossary changes through pull requests, but there's a catch. A glossary change triggers fresh generation for machine-produced records on the next update. Records already marked reviewed keep their wording. So a terminology fix also has to reach the reviewed translation memory wherever it matters, or the old phrasing sticks around.
Running an update yourself
Each language's translation/README.md covers environment setup, fetching the English source, previewing changes, generating translations, reviewing results and building the lesson. The Japanese, Spanish, Simplified Chinese and French repositories all include one. The Urdu caveat from earlier still applies.
In the Japanese repository, after configuring the upstream remote as its guide describes, a maintainer runs something like this:
git fetch upstream main uv run --locked scripts/translate.py --source-ref upstream/main --dry-run uv run --locked scripts/translate.py --source-ref upstream/main --update-memory git diff -- episodes translation Rscript scripts/build.R
The dry run is the part I'd run first every time. It shows which passages can be reused and which need new translation, without generating text or writing lesson files. The --update-memory step saves new records to translation/seed-cache.json and source provenance to translation/source-manifest.json, so reviewers can see exactly what changed. The local runtime cache under .cache/translation/ is ignored by Git. Other editions may use a different upstream remote name, so check the README in the repository you're updating.
The translator also refuses to overwrite a lesson with local edits. Small build adaptations get recorded separately and checked against the expected source. Images, datasets and episode ordering still need manual maintenance when the English lesson changes. The pipeline handles prose well. It doesn't handle everything around the prose.
Local generation versus a GitHub-only review
The workflow pins the model revision and locks its Python dependencies. It records the source revision and model provenance alongside the translation resources, which matters if someone needs to explain later why a passage reads the way it does.
Generating new text with the current implementation requires an Apple silicon Mac, Python 3.12 and uv. The first model download is about 6 GB. Planning updates and replaying cached translations can run with Python 3.12 alone on other platforms. Reading the lessons and contributing a review on GitHub require no model installation at all. That split is deliberate: the people best placed to catch a bad term in a Spanish exercise don't need a GPU workstation.
The translation memory is where community review pays off over time. Newly generated records are marked machine. Once a reviewer checks a record in translation/seed-cache.json, they can mark it reviewed. From then on, that wording is kept for matching source text in the same episode and language pair, even if the model or glossary settings change later. The French repository's translation/README.md spells out that review process.
Where reviewers can help most
A successful build proves the lesson renders. It doesn't prove the lesson teaches the same thing. A translation can read fluently while quietly changing an exercise condition, swapping in an unfamiliar technical term, or dropping a distinction the English text relied on. The Simplified Chinese repository's translation/README.md flags its initial memory as machine generated and in need of review. That honesty is the right default for every edition.
If you read one of these languages, try an episode and compare it against the English lesson. Three areas need the most help:
- Language and terminology: suggest clearer explanations and vocabulary your local research community actually uses.
- Exercises and teaching: check that questions, solutions and instructor notes keep the original learning goals.
- Corrections that carry forward: help maintainers update the glossary, context guidance and translation memory alongside the lesson text, so fixes don't get overwritten.
To report a problem, open an issue in the relevant repository with the episode name, the passage in question and a suggested correction or explanation. Pull requests are welcome too, provided you follow that repository's contribution and translation guides. If you want to review translations, add support for another language or translate a different lesson, join the #documentation-translation channel on the Bioconductor community chat.
The lessons' text is published under CC-BY-4.0 and the code under BSD 3-Clause. The next useful test is the Urdu edition, once its updater configuration is adapted, because that will show whether the pipeline generalises beyond the languages it was built around.