Where annotation runs, and how it calls the model

Annotation reads a Signal Dataset snapshot, which is what rfgen generate writes.

Three settings look like they might be the same decision. They are not.

Setting

Decides

Does not decide

execution_mode

Which machine holds the loop: local or dataproc_serverless

How the model is called

backend

How the model is called: local_concurrent (one request per record) or gemini_batch (many per job)

Where the loop runs

inference.max_records_per_wave

How many records go in one wave: one provider job under gemini_batch, one staged shard and resume unit under either backend. It is part of the run’s identity: changing it stages fresh work, and is refused outright once the set has published.

Where the loop runs

A run picks one value from each of the first two rows. dataproc_serverless with gemini_batch is a Dataproc batch calling the Gemini Batch API: two different things called “batch”, composed.

Pick a backend by dataset size

backend: local_concurrent   # a smoke test: one call per record, errors arrive immediately
backend: gemini_batch       # a dataset: many records per job, roughly half the price

local_concurrent issues one synchronous request per record, eight at a time by default. That is the right shape for ten records and the wrong shape for ten million: at a couple of seconds per call, a million records is measured in days, and raising the concurrency finds the provider’s rate limit sooner.

gemini_batch inverts that. One job carries many records, the provider schedules them, and the price is roughly half. It is the default choice for anything you intend to train on.

Both write the same annotation set. The backend changes what the run costs and how long it takes, never what it produces.

Pick an execution mode by how long the run takes

gemini_batch blocks until each job reaches a terminal state, so the process that submitted it has to stay alive for the whole run. On a laptop that is fine for a wave; it is not fine for a corpus that takes a day. execution_mode: dataproc_serverless moves that process onto Dataproc.

Changing the backend is one line. Moving the loop is not, because a batch cannot read your disk or your shell: it also needs a gs:// dataset_uri, inference.api_key_secret, and a dataproc: block naming the project, region, and dependency bucket. The four annotation modes carries the exact configuration and the polling loop.

submit returns as soon as the batch is accepted, and wait then advances one polling cycle per call rather than blocking until the run finishes.

The four combinations

#

execution_mode

backend

Qualified

1

local

local_concurrent

Yes, local path and gs://, hosted API and local model server

2

local

gemini_batch

Yes, local path and gs://

3

dataproc_serverless

local_concurrent

Yes, against the current pin

4

dataproc_serverless

gemini_batch

Yes, against the current pin

What each mode is for, and a copyable configuration for each, is on the task page: The four annotation modes.

“Qualified” means a recorded live run of six records, not a throughput, cost, or reliability measurement, and not a promise about your project. See gs:// snapshots, Dataproc Serverless, and backend: gemini_batch.