Skip to content

feat(models): add Google Cloud Translation as a LID model - #18

Open
malteos wants to merge 1 commit into
mainfrom
feat/google-translate-model
Open

feat(models): add Google Cloud Translation as a LID model#18
malteos wants to merge 1 commit into
mainfrom
feat/google-translate-model

Conversation

@malteos

@malteos malteos commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Closes #11.

Why

Adds GoogleTranslate, so the commercial detector can be compared against the open models already on the leaderboard.

Builds on #17: the wrapper returns the API's confidence as the prediction score.

v2, not v3

The issue links the v3 codelab, but v3 cannot be used with an API key. detectLanguage refuses it outright on both transports:

401 API keys are not supported by this API. Expected OAuth2 access token
or other authentication credentials that assert a principal.
[reason: "CREDENTIALS_MISSING"]

It wants OAuth2 / Application Default Credentials plus a project id in the parent path. v2 accepts an API key and needs no project id.

v2 is also the better fit on the merits. It detects a whole list of texts per request, where v3 takes a single content string per call and batchTranslateText covers translation only. That turns a 373K-sample benchmark from 373K HTTP calls into a few thousand.

The client library ignores client_options={"api_key": ...} and falls through to ADC, so the key is passed as google.auth.api_key.Credentials, which attaches the x-goog-api-key header.

Credentials

GOOGLE_TRANSLATE_API_KEY is read from the process environment and nothing else. The model does not load .env files; setting the variable is the caller's job. A missing key fails at load() with a message naming it.

Cost

Detection is billed per character at the same rate as translation, $20 per million characters, with the first 500K each month free. Measured on the cleaned text that is actually sent, since predict() applies the OpenLID normer first:

dataset samples billable chars cost
commonlid_nano 1,507 305,431 ~$6
commonlid 373,230 76,713,413 ~$1,534

The nano run fits inside the monthly free tier. No evaluation has been run, and none should be without agreeing the spend first. Re-runs are free because the evaluator's PredictionCache covers them.

Implementation notes

  • Each batch is re-split to stay under the per-request segment and size caps, and the pieces go out concurrently. Raise --batch-size for larger requests.
  • Retries 429 and transient errors with bounded backoff. A dead endpoint or a bad key raises rather than being silently scored as abstention.
  • Blank text short-circuits before the call: a rejected request is still billed.
  • Detected BCP-47 codes are cut at the first - before the existing ISO 639-3 conformance pass, so zh-CN becomes zho. Google's legacy codes are already handled by the deprecation table, so iw becomes heb.
  • discover_supported_languages() asks the API, giving 187 conformed codes from 195 raw, with nothing dropped by the conformance pass.
  • New optional extra commonlid[google-translate], named after the service rather than the vendor so a future Google model gets its own. Mirrored into dev so the tests exercise the real client, and added to all. New make install-google-translate.

Testing

make check passes: 277 tests, 95.8% coverage, ruff and mypy strict clean.

The model tests never touch the network; they swap in a fake client or monkeypatch the library out of sys.modules. They cover the missing-extra and missing-key errors, code conformance including zh-CN and a confidence surviving an unmappable code, blank-text short-circuiting with zero API calls, chunking by both segment and character budget, order preservation across the thread pool, and the retry and give-up paths.

Verified against the live API. A three-sample evaluator run, costing a few hundred characters, produced:

{"correct": true, "gold": "lav", "idx": 2, "pred": "lav", "score": 0.6271151304244995, ...}

@malteos
malteos force-pushed the feat/google-translate-model branch 2 times, most recently from 6af68ac to a182c83 Compare September 9, 2026 12:54
Closes #11. Registers `GoogleTranslate`, wrapping Cloud Translation's
`detect` method. The API key is read from `GOOGLE_TRANSLATE_API_KEY` in the
process environment, which the caller is expected to have set; the model
does not read `.env` files itself.

Uses Cloud Translation v2, not v3. v3 `detectLanguage` refuses API-key
authentication outright ("401 API keys are not supported by this API") on
both its gRPC and REST transports and wants OAuth2 / ADC plus a project id.
v2 accepts an API key, needs no project id, and detects a whole list of
texts per request, where v3 takes a single string per call and
`batchTranslateText` covers translation only. Batching turns a 373K-sample
benchmark from 373K HTTP calls into a few thousand.

The wrapper re-splits each batch to stay under the per-request segment and
size caps, sends the pieces concurrently, retries 429 and transient errors
with bounded backoff, and short-circuits blank text so a rejected request is
never billed. Detected BCP-47 codes are cut at the first `-` before the
existing ISO 639-3 conformance pass, so `zh-CN` becomes `zho`. The API's
`confidence` is kept as the prediction score.

New optional extra `commonlid[google-translate]`, named after the service
rather than the vendor so a future Google model gets its own.
@malteos
malteos force-pushed the feat/google-translate-model branch from a182c83 to e2d87e1 Compare September 9, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Google Translate LID model

1 participant