Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

33: Exporting models for Hugging Face and serving engines

E3301

Not a forward function a serving engine can run. A language model that serving engines run, as --vllm and --gguf require, must take the model, the token ids, [b n] Index[V] with V a dim, and optionally their positions, [b n] of an integer dtype, and give the next-token logits, [b n V]. Other parameters need defaults.

fn forward(m: Lm, ids: [b n C] Index[V]) -> [b n C V]:
error[E3301]: `forward` isn't a language model's forward function a serving engine can run

See Serving engines.

E3302

No output layer a serving engine can run. A serving engine runs the output layer itself, only for the tokens it samples, so the forward function must end with one return of linear(h, m.W) or h |> linear(m.W), with m.W a param of the model of shape [V D] and no bias.

return linear(x, m.emb, m.b_out)
error[E3302]: a serving engine needs the logits to come from an output layer it can run

Return the output layer’s result directly, and do anything else before it. See Serving engines.

E3303

No embedding a serving engine can run. A serving engine looks the tokens up in its own embedding layer, so the token ids must be used once, by embedding(ids, m.E) with m.E a param of shape [V D], and the embedding table and the output layer, which the engine holds, must be read nowhere else.

x = embedding(ids, m.emb) * mean(m.emb)
error[E3303]: `emb` is the embedding table, which a serving engine holds itself

See Serving engines.

E3304

Works across the positions a serving engine packs. A serving engine packs the tokens of many requests along the sequence axis n, one request after another, so everything the forward function does along n, in any function it passes n to, must treat each position on its own, except scaled_dot_product_attention with attn_mask=causal[n n] written in the call, which the engine replaces with its own. A sum, a softmax or a contraction across n, attention written by hand, attention with another mask, and positions computed from n are this error.

|> softmax(over=m)
error[E3304]: a serving engine can't run this: this works along `n`, which mixes its positions

Write attention as scaled_dot_product_attention(q, k, v, attn_mask=causal[n n]), and take positions as a parameter. See Serving engines.

E3305

Attention a serving engine can’t run. A serving engine keeps the keys and values of each attention in its cache, with one number of heads and one head width: every attention’s queries, keys and values must have one shape, [b H n Dh], with H and Dh dims, the same for every attention, and there must be at least one.

fn forward(m: Lm, ids: [b n] Index[V]) -> [b n V]:
error[E3305]: `forward` has no attention

Repeat keys and values with fewer heads to H before attention. See Serving engines.

E3306

Exported function that doesn’t take the model first. shapescript export --hf exports a model: its fields are the Hugging Face model’s weights, and the function it’s exported with becomes its forward, taking the function’s other parameters. So the function’s first parameter must be the model.

fn classify(x: [b D], m: Classifier) -> [b C]:
error[E3306]: `classify` must take the model first, to be exported as one

Make the model the first parameter. See Serving engines.