Skip to content
ACS Infra

Completions

POST /v1/completions continues one prompt, or several prompts, with a Base model. It follows OpenAI's completions API, so the openai SDK calls it with client.completions.create(...). Sample continuations shows the tasks, and the API reference has the schema of every field.

Request fields

prompt is required. Apart from model and max_tokens, a field that you leave out, or sets to null, gets OpenAI's default, or the value that turns a vLLM field off. The model's own generation_config.json never sets a default.

A field marked vLLM comes from vLLM, the engine that runs the Base models in Inference, and is not in OpenAI's API. A field marked vllm-lens comes from vllm-lens, the vLLM plugin that reads and changes the residual stream. The openai SDK sends both kinds only in extra_body (Send vLLM's fields).

What to continue

FieldDefaultWhat it does
modelthe default modelThe id of a model from GET /v1/models, such as llama-8b. Left out, the model that the list marks default.
promptrequiredA text, a list of token ids, or a list of several texts or several token-id lists.
max_tokensthe context leftThe most tokens to write for each choice. The rules are under this table.
n1The number of choices to write for each prompt.
stopnoneA text, or a list of at most 4 texts. The model stops before it writes one of them.
echofalsePut the prompt in front of the generated text.
add_special_tokenstruevLLM. Add the model's special tokens, such as BOS, to a text prompt. Inference adds none to token ids.

The rules of max_tokens:

  • Left out or null, it is the model's max_model_len less the prompt's tokens as the Hold counts them. It is at least 1 and at most 32,000, and at most 15,600 without stream.
  • A request with more than one prompt, or with n above 1, must set it.
  • A request writes at most 32,000 tokens in all: the prompts × n × max_tokens (Size caps).
  • Without stream, a value above 15,600 gets 400 deadline_infeasible. Inference cannot write more within the API's 14-minute wait (Requests without a stream).
  • The prompt and max_tokens together must fit the model's max_model_len (Prompt too long).
  • Near the end of your tokens, the API lowers it to what your Budget can hold. The header X-Acs-Max-Tokens-Clamped then says so (Near the end of your tokens).
  • In a Job's request and in a Loom Branch, it is 16 when you leave it out.

How to sample

FieldDefaultWhat it does
temperature1Divide the scores of the tokens by this number before sampling, from 0 to 2. 0 takes the likeliest token each time.
top_p1Sample only from the likeliest tokens whose probabilities add up to top_p. More than 0 and at most 1.
top_k0vLLM. Sample only from the top_k likeliest tokens. 0 or -1 turns the filter off.
min_p0vLLM. Leave out the tokens less likely than min_p times the likeliest token, from 0 to 1. 0 turns the filter off.
presence_penalty0Make a token that is already in the generated text less likely, or more likely for a negative number, from -2 to 2.
frequency_penalty0As presence_penalty, but more for each time that the token is already in the generated text, from -2 to 2.
repetition_penalty1vLLM. Make the tokens of the prompt and the generated text less likely by this factor, more than 0. 1 turns the penalty off.
seednoneSample with this seed, 0 or more.

At temperature 0, or with the same seed, the same request on the same model gets the same tokens and log probabilities again, with one exception. vLLM batches your request with other requests. The batch can change a log probability by a little, and now and then a token where two tokens are almost equally likely.

What to return

FieldDefaultWhat it does
logprobsnoneReturn the log probability of each generated token, and of the logprobs likeliest tokens at its position. 0 to 100.
prompt_logprobsnonevLLM. Return the log probability of each prompt token, and of the likeliest tokens at its position. 0 to 100, or -1 for the whole vocabulary of one prompt. Not with stream.
streamfalseSend the Completion as Server-Sent Events.
stream_optionsnoneOnly with stream. {"include_usage": true} adds a last chunk with the usage of the request. With "continuous_usage_stats": true (vLLM), each chunk has the usage of its choice so far, with or without include_usage.
output_residual_streamnonevllm-lens. Return the Activations at these Layers, or true for every Layer. false returns none. Only for one prompt and an n of 1.
apply_steering_vectorsnonevllm-lens. Add these Steering vectors to the residual stream. Only for one prompt and an n of 1.

Read token probabilities, Read Activations, and Steer a Completion show these fields in use.

Other fields

FieldDefaultWhat it does
priority0vLLM. 0 or more. A request with a lower number runs first. Requests with the same number wait in the order that they arrived. null is 0. A text of digits, such as "5", and true or false count as their number.
usernoneOpenAI's id for the person who asked. Inference gets it and does nothing with it.

Strict validation

The API checks the type of every field before the request reaches Inference, and it refuses what it does not know. A wrong value never falls back to a default (Why the API is strict).

  • A field that the API does not know gets 400 with the code invalid_request (Unknown field).
  • A value of the wrong type gets 400, with param set to the field. A number in a string, such as "2", is not a number, except for priority. 1 and "true" are not booleans. A whole number such as 1 is valid for a decimal field such as temperature.
  • The API checks the ranges of logprobs, prompt_logprobs, seed, priority, and the sampling fields in How to sample. It also checks the shape of the Activations and Steering vector fields, and the size caps.
  • The API refuses n above 1 at a temperature below 0.00001, where Inference picks the likeliest token each time.
  • The API refuses stream_options without stream: true, and prompt_logprobs with stream: true.
  • Inference checks the other values, for example that each token id of a prompt is in the model's vocabulary. The API passes on Inference's 400, with Inference's message and param.

This request sends max_tokens as a string, so the API refuses it:

curl "$ACS_API_BASE/completions" \
  -H "Authorization: Bearer $ACS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "llama-8b", "prompt": "The sky is", "max_tokens": "2"}'
Error
{
  "error": {
    "message": "Invalid type for 'max_tokens': expected a number.",
    "type": "invalid_request_error",
    "param": "max_tokens",
    "code": "invalid_request"
  },
  "request_id": "req_9f2c4e1a7b3d4c5e8f6a0b1c2d3e4f5a"
}

Size caps

Each cap keeps one request from using too much memory in the API or in Inference. A request over a cap gets 400 invalid_request_error, with param set to the field, and does not reach Inference. The caps count a prompt's tokens as the Hold counts them, with the model's tokenizer.

CapFieldWhy
The prompts × n is at most 128nOpenAI's limit on n.
The prompts × n × max_tokens is at most 32,000, and a max_tokens of 0 counts as 1max_tokensThe Hold of a request is then at most its prompt and 32,000 tokens.
At most 4 stop textsstopOpenAI's limit.
prompt_logprobs: -1 takes at most 256 prompt tokens in all × n, or 16 with output_residual_streamprompt_logprobsEach prompt token then has a log probability for each token of the vocabulary (128,256 for meta-llama/Llama-3.1-8B). Inference holds them all in memory.
At most 33,554,432 (2^25) top log probabilities of the prompt. Each prompt token × n has k + 1 for prompt_logprobs k, and k + 1 more for logprobs k with echo.prompt_logprobs or logprobsInference holds each one in memory, and the answer carries each one.
Layers × tokens × the model's hidden size is at most 33,554,432 (2^25) for one capture. The tokens are the prompt's and max_tokens.output_residual_streamThe API reads the Activations of a capture as one text.
At most 8 Steering vectors, and 2,097,152 (2^21) numbers in all of them. A vector with position_spans counts once for each position of its spans.apply_steering_vectorsThe API sends the numbers to Inference as float32: at most 8 MiB.

llama-8b has a hidden size of 4,096, so one capture is at most 8,192 Layers × tokens. That is all 32 Layers for 256 tokens, or 1 Layer for 8,192 tokens.

The whole request body is at most 8 MiB on every route, and a larger body gets 413 (Status codes). The body can cap the Steering vectors first: in JSON, 8 MiB holds about 699,000 numbers of 12 characters each. Encoded Steering vectors take about a tenth of those bytes, so eight vectors over all 32 Layers of meta-llama/Llama-3.1-8B fit.

This request asks for 2 choices of 16,001 tokens, which is 32,002 tokens in all:

curl "$ACS_API_BASE/completions" \
  -H "Authorization: Bearer $ACS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "llama-8b", "prompt": "The sky is", "max_tokens": 16001, "n": 2}'
Error
{
  "error": {
    "message": "At most 32000 generated tokens in all: n = 2 times max_tokens = 16001 for each of 1 prompts is 32002.",
    "type": "invalid_request_error",
    "param": "max_tokens",
    "code": "invalid_request"
  },
  "request_id": "req_9f2c4e1a7b3d4c5e8f6a0b1c2d3e4f5a"
}

Response fields

The Quickstart shows a whole Completion.

FieldWhat it is
idThe id of the Completion, from Inference.
objectAlways "text_completion".
createdWhen Inference made the Completion, in Unix seconds.
modelThe model that wrote it.
choicesOne choice for each prompt and each of its n samples, in the order of their index.
usageThe prompt_tokens, completion_tokens, and total_tokens of the whole request. prompt_tokens counts each prompt once, whatever n is.
activationsThe Activations, only when the request has output_residual_stream.

Each choice has these fields:

FieldWhat it is
indexp * n + i for choice i of prompt p.
textThe generated text. With echo, the prompt comes first.
logprobsnull, or the lists that logprobs asks for.
finish_reason"length" when the choice reached max_tokens or the model's context length. "stop" when the model wrote its end-of-text token or a stop text. Inference can add other reasons.
stop_reasonThe stop text that ended the choice, or null. With finish_reason "stop", null means that the model wrote its end-of-text token.
prompt_logprobsnull, or the list that prompt_logprobs asks for, with null for the first prompt token.

In a stream, each data: event is a chunk with the same id, object, created, and model. Its choices has the next text of one choice, with finish_reason and stop_reason null until the last chunk of that choice. With include_usage, a last chunk has "choices": [] and the usage of the whole request. The Activations come in a last chunk of their own, and data: [DONE] ends the stream. Every 5 seconds the stream also has a : keepalive comment line, which SSE clients skip (Requests with a stream).

Not in the API

The API does not take these fields and routes of OpenAI's API:

  • best_of. vLLM accepts it and ignores it, so the API refuses it as an unknown field. n returns each choice instead.
  • suffix. vLLM supports it only for models that fill in the middle of a text.
  • logit_bias.
  • Chat. The API applies no chat template (No chat template). POST /v1/chat/completions gets 400 invalid_request_error with the message This API serves Base models, which have no chat format: send POST /v1/completions with a prompt instead of POST /v1/chat/completions with messages.

On this page