M2M100 418M failed the quality gate on real articles. Measured on a 420-word
post: "frijoles" came back as "Beeren" (berries), "rompe la idea" as "breitet
die Idee" (spreads it — the opposite), "así sabe mi barrio" as "so weiß mein
Viertel" (knows, not tastes), and the opening sentence was not grammatical
German. Invented non-words throughout ("verforscht", "Treffenraum").
The pipeline itself was never at fault — masking held, structure survived,
zero placeholder failures across 14 files. The model was.
OPUS-MT is stronger on these specific pairs, and fits the existing CX22 with
no server upgrade, which was the constraint. Licence moves from MIT to
CC-BY-4.0, so attribution now ships with the platform.
Routes are verified against Hugging Face rather than assumed — the earlier
research could not reach HF, and half the names it guessed do not exist:
es -> de opus-mt-es-de (small, ~74M)
de -> es opus-mt-tc-big-de-es (tc-big, ~237M)
es <-> pt-br opus-mt-tc-big-itc-itc (>>pob<< / >>spa<<)
de <-> pt-br no model in either direction — pivots through Spanish
Models now live at /srv/mt-models and are mounted read-only rather than baked
into the image. Model choice has needed iteration, and a directory swap beats
a 1GB image rebuild each time. It also keeps model conversion out of the image
build, which matters on a box that OOM-killed the last conversion.
MT_PROVIDER=m2m100 still selects the old engine.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NizVpJ2dwzCbjCrTLCjeHn
54 lines
1.9 KiB
YAML
54 lines
1.9 KiB
YAML
# Woodpecker CI: translate → build → deploy
|
|
#
|
|
# Triggered by the Gitea push webhook. The translate step replaces the old
|
|
# synchronous WordPress save_post hook: publishing in Decap is one git commit,
|
|
# translation happens here, asynchronously, and every generated sibling lands
|
|
# as a reviewable bot commit.
|
|
#
|
|
# Translation is self-hosted — OPUS-MT runs on CPU inside the image, so there
|
|
# is no API key and no third-party request. Before the first run, on the server:
|
|
# bash scripts/fetch-models.sh # -> /srv/mt-models
|
|
# docker build -t vienalatina/translate:2 docker/translate
|
|
#
|
|
# The models are mounted rather than baked in, so swapping them later does not
|
|
# mean rebuilding the image. The repo must be marked "trusted" in Woodpecker
|
|
# for this mount, which it already is for the deploy step.
|
|
#
|
|
# Secrets to configure in Woodpecker (repo settings → secrets):
|
|
# gitea_push_token — Gitea token for the translations bot user
|
|
# (translations@vienalatina.com) with repo write access
|
|
#
|
|
# The deploy step writes to the Caddy web root via a host mount, which
|
|
# requires the repo to be marked "trusted" in Woodpecker.
|
|
|
|
when:
|
|
- event: push
|
|
branch: main
|
|
|
|
steps:
|
|
translate:
|
|
image: vienalatina/translate:2
|
|
pull: false # built locally on the server, never fetched from a registry
|
|
volumes:
|
|
- /srv/mt-models:/opt/mt/models:ro
|
|
environment:
|
|
GITEA_PUSH_TOKEN:
|
|
from_secret: gitea_push_token
|
|
commands:
|
|
- python scripts/translate.py
|
|
|
|
build:
|
|
image: hugomods/hugo:0.135.0
|
|
commands:
|
|
# Bundle Decap locally so the /admin page makes zero third-party requests.
|
|
- wget -q -O static/admin/decap-cms.js https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js
|
|
- hugo --minify
|
|
|
|
deploy:
|
|
image: alpine:3.20
|
|
volumes:
|
|
- /var/www/vienalatina.com:/deploy-target
|
|
commands:
|
|
- apk add --no-cache rsync
|
|
- rsync -a --delete public/ /deploy-target/
|