text/embeddings@1
One batch of texts in, one normalised 768-dimension vector per text out, from BAAI/bge-base-en-v1.5, an English model, through sentence-transformers.
A unit
Section titled “A unit”Up to 1,000 texts of up to 512 tokens each (the model’s context, so 512k tokens in all), counted with the model’s own tokenizer, including the two special tokens it adds to every text: 510 of your own. A longer text or a bigger batch fails with the reason, naming the first text over the limit; nothing is truncated or split. Split long documents into passages before they go into the manifest.
Manifest fields
Section titled “Manifest fields”| Field | Required | Meaning |
|---|---|---|
texts |
one of the two | a list of {"id": ..., "text": "..."} objects |
url |
one of the two | an http or https address of a JSONL file with one {"id": ..., "text": "..."} per line, at most 64 MiB, or the key of such a file your org uploaded (unitfabric upload, or POST /v1/uploads with "kind": "input"), which the node fetches before the worker begins the unit, so the worker reads it as a file under /in; anything else is refused when you submit |
unit_id |
no | your name for the unit: 1 to 64 letters, digits, ., _ or -, starting with a letter or digit; its results are stored under it. By default units are numbered by line: 000000, 000001, … |
A manifest line is at most 65,536 characters, so texts written into the manifest suit small batches; put a full batch in a JSONL file and give its url. Each id comes back with its vector, so it can be any JSON value.
Example
Section titled “Example”batches.jsonl:
{"unit_id": "faq", "texts": [{"id": 1, "text": "How do I reset my password?"}, {"id": 2, "text": "Where is my invoice?"}]}{"unit_id": "docs-0001", "url": "https://example.com/corpus/passages-0001.jsonl"}{"unit_id": "docs-0002", "url": "https://example.com/corpus/passages-0002.jsonl"}job.yaml:
name: corpus embeddingstemplate: text/embeddings@1input: batches.jsonlWhat comes back
Section titled “What comes back”embeddings.jsonl for each unit, one line per text in input order: {"id": <your id>, "vector": [<768 numbers>]}. Vectors have unit length, so cosine similarity is a dot product, and are rounded to six decimals. Each unit’s directory also holds done.json: {"unit_id": ..., "artifacts": ["embeddings.jsonl"], "seconds": ...}.
Limits
Section titled “Limits”- Runs on the node’s GPU when it has one, otherwise on 4 CPUs; 8 GB of memory and 5 GB of scratch disk. A unit costs the same either way.
- 900 s per unit. A unit still running then is stopped and tried again, up to the job’s attempts (
unit.max_attempts: 3 by default, 1 to 10), and a unit that never completes is not billed. A batch over a bound fails each attempt the same way. - A
urlthe worker downloads is at most 64 MiB and must come within 450 s (half the unit’s time), with no 60 s stretch without data, through our gateway, which allows ports 80 and 443 only. An uploaded file is fetched by the node itself before the unit begins, not through the gateway, within 900 s that are not the unit’s, and is held to the same 64 MiB. - Checkpointing is off: a unit cut short by a node failure starts again from the beginning, and is billed once.
- A manifest is at most 32 MiB.
Price per unit: see pricing.
Benchmarks
Section titled “Benchmarks”The price is measured on a full unit: 1,000 texts of exactly 512 tokens each, the two special tokens included. On 4 CPUs of an Intel Core i9-14900K a bench unit took 270, 292 and 327 s in three runs, about a third of the time limit. On GPUs it is measured on GPU hosts at launch.