Large models (peach-models)
peach-models is a shared service that runs large AI models on GPUs for every member on the platform. You don't deploy, size or maintain a model yourself. You call an API and get a result.
That matters because GPUs are scarce and expensive. If every codops loaded its own embedding model, each would hold a GPU that sits idle most of the day. Running each model once, behind one service, keeps the hardware busy and gives every codops access to models none of them would run alone.
| API | https://api.models.peach.ebu.io |
| Web UI | models.peach.ebu.io |
| Interactive API reference | https://api.models.peach.ebu.io/docs |
This section has four pages:
- Overview (this page): what the service does, how it runs, and how to call it.
- How models run: a short primer on GPUs, vLLM, and why some models handle many requests at once while others take one at a time. Read this if you want to make your calls fast.
- Limits and errors: queues, timeouts, HTTP status codes, and how to retry.
- Code examples: Python examples you can copy, including parallel requests with retries.
What is available
The service covers the usual jobs a recommendation or content platform needs:
- Embeddings: turn text into vectors for similarity search and related content.
- Speech to text: transcribe audio, with a streaming variant.
- Translation: between 55 languages.
- Text generation: a chat-style LLM.
- Classification: purpose-built models such as constructiveness scoring.
- Text to speech and image generation, when those models are enabled.
The set of models changes over time, so rather than keep a list here, ask the service:
GET https://api.models.peach.ebu.io/v1/models
Or open the web UI. It shows every model with its status, replica count and queue, and has a playground for trying a model without writing any code.
How it runs
Where the GPUs are
Most models run on 8x NVIDIA L40S GPUs in our own bare-metal server, rather than on rented cloud GPUs. The GPUs are passed through to virtual machines that join our Kubernetes cluster as hybrid nodes, so our own hardware and cloud machines form one cluster. When demand is high, extra cloud GPU machines can be added. You call the same API either way.
A request goes through three steps:
- The API front door checks your codops and token, works out the request's priority, and records usage for your codops.
- A queue per model holds requests until the model has room. How this queue behaves depends on the kind of model (see How models run).
- A model replica runs the request on a GPU. A replica is one loaded copy of a model. Popular models have several replicas, others have one.
Each model is loaded into GPU memory once and stays there, so requests do not pay a loading cost. After a restart or a scale-up, a model can take from 30 seconds to a few minutes to load. During that time requests wait or are rejected with a retryable error.
Calling it from a task or endpoint
The easiest route is pipe_algorithms_lib.deep_serve, which wraps the service and
picks up your credentials from the environment:
from pipe_algorithms_lib.deep_serve import calculate_embeddings
vectors = await calculate_embeddings(
["some text", "some other text"],
model="labse",
)
It offers three helpers:
| Helper | Does |
|---|---|
calculate_embeddings(texts, model=..., dimensions=..., normalize_embeddings=...) |
embeds one string or a list of them |
transcribe(audio_file, model=..., language=...) |
speech to text |
model_inference(model, query) |
any other model's inference endpoint |
All three are async, so call them from an async def task or endpoint.
Credentials resolve automatically: the codops from CODOPS and the token from
CODOPS_{CODOPS}_SECRET, both already set for you on the cluster and in PEACH Lab.
PEACH_MODELS_HOST points the client at a different environment.
Calling it over HTTP
There are two API styles, both authenticated per codops.
OpenAI-compatible
The /v1/... routes follow the OpenAI API, so an existing OpenAI client library
works if you point its base URL here. Authenticate with a bearer token of
{codops}:{token}:
curl https://api.models.peach.ebu.io/v1/embeddings \
-H "Authorization: Bearer ${CODOPS}:${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"model": "labse-embedding", "input": "hello world"}'
Available routes: /v1/chat/completions, /v1/embeddings,
/v1/audio/transcriptions, /v1/audio/speech, /v1/images/generations,
/v1/translations and /v1/models. Translation is not part of the OpenAI API, so
/v1/translations has its own simple shape (see
Code examples).
Native
The native routes take codops and token in the request body and offer options
the OpenAI shape has no room for, such as priority and webhook:
curl https://api.models.peach.ebu.io/models/labse-embedding/embeddings \
-H "Content-Type: application/json" \
-d '{"codops": "<codops>", "token": "<token>", "input": ["hello", "world"],
"dimensions": 1024, "priority": "high"}'
Per model type: /models/{model}/embeddings, /transcribe, /transcribe/stream,
/translate, /tts, /images and /inference. The full parameter list for each
is in the interactive reference.
Priority
Every request has a priority. On models that take one request at a time, the service serves higher priorities first when the queue is long, and keeps part of the capacity free for interactive work. Use it honestly: it is what stops a large overnight batch from delaying someone's live page.
| Preset | Value | Use for |
|---|---|---|
realtime |
0 | live streaming, a user waiting for the response |
high |
2 | time-sensitive work |
normal |
5 | the default for batches |
low |
7 | background work in a task |
batch |
9 | large batch jobs with no deadline |
A number from 0 (highest) to 10 works too. If you leave it out, a single-item
request (one text, one audio file, one translation) counts as high, and an
embeddings request with a list counts as normal.
Within the same priority, codops take turns, so one member sending a lot of requests cannot block another member's requests.
Note
The translation models ignore priority. They process many requests at the same time in arrival order; see How models run.
Good habits
- Retry the retryable errors.
503,429and504are normal under load. Wait forRetry-Afteror your own backoff, whichever is longer, and try again. See Limits and errors. - Send embeddings as lists, up to 2048 texts per call, rather than one call per text.
- Send translations as separate, parallel requests, one paragraph each, rather than one long text. See How models run.
- Use
batchorlowpriority and a webhook for bulk work, so live traffic stays fast. - Access is per codops. Your token identifies you, and usage is shown per codops on the UI's stats page.
Related
- Vector Embeddings: using embeddings for similarity search.
- Streaming APIs and Large models: for a model you host yourself inside an endpoint, rather than calling this service.
- Build your first feature: where a call like this fits in a task.