GizStack
View .mdOpen in ChatGPTOpen in Claude

gizml:llm

language models, fast on any hardware.

A model family is a recipe: its config.json read as an Arch, and the names of its tensors. Every family runs on the same operations, so a new family is one recipe. convert turns a Hugging Face folder into this module's format once: each linear is stored in a format (Formats), after a Hadamard rotation of each block of 128 inputs, in the order the GPU reads it. load opens a converted model on the best device it finds, and its Engine runs steps of many sequences at once.

gizlang
import * as Llm from "gizml:llm";

Types

Message

gizlang
type Message = { role: string; content: string; reasoning?: string; calls?: Vec<Hub.Call>; }

A message of a chat: its role ("system", "user", "assistant" or "tool") and text; an assistant's reasoning before its answer and the tools it called.

  • role: string
  • content: string
  • reasoning: _gizlang_sdk_core.Option<string>
  • calls: _gizlang_sdk_core.Option<Vec<gizlang_hub.Call>>

Arch

gizlang
type Arch = { family: string; vocab: i64; dim: i64; ffn: i64; layers: i64; kinds: Vec<i64>; eps: f64; heads: i64; kv: i64; headDim: i64; rotary: i64; rope: Vec<f64>; qkNorm: bool; gated: bool; bias: bool; kHeads: i64; vHeads: i64; kDim: i64; vDim: i64; conv: i64; tied: bool; mtp: i64; context: i64; prefix: string; sections: Vec<i64>; hc: i64; hcRank: i64; experts: i64; topK: i64; ple: i64; eos: i64; sigmoidGate: bool; }

What a model computes, as its family's recipe reads config.json. Attention: heads query heads of headDim over kv key-value heads, rotary positions on the first rotary dimensions of a head (rope their inverse frequencies), RMS norms of q and k (qkNorm), a sigmoid gate on the output (gated), biases on q, k and v. Recurrent layers: kHeads query-key heads of kDim, vHeads value heads of vDim, a causal convolution of conv taps. mtp layers predict a further token.

  • family: string
  • vocab: i64
  • dim: i64
  • ffn: i64
  • layers: i64
  • kinds: Vec<i64>
  • eps: f64
  • heads: i64
  • kv: i64
  • headDim: i64
  • rotary: i64
  • rope: Vec<f64>
  • qkNorm: bool
  • gated: bool
  • bias: bool
  • kHeads: i64
  • vHeads: i64
  • kDim: i64
  • vDim: i64
  • conv: i64
  • tied: bool
  • mtp: i64
  • context: i64
  • prefix: string
  • sections: Vec<i64>
  • hc: i64
  • hcRank: i64
  • experts: i64
  • topK: i64
  • ple: i64
  • eos: i64
  • sigmoidGate: bool

Bits

gizlang
type Bits = { layers: i64; head: i64; }

The format of each kind of linear (Formats): layers for the layers, head for the output head.

  • layers: i64
  • head: i64

Model

gizlang
type Model = { arch: Arch; folder: string; tokenizer: Tokenizer; stops: Vec<i64>; template: string; system: string; think: bool; calls: bool; efforts: Vec<string>; sampling: Sampling; embed: Stored; layers: Vec<Layer>; norm: i64; head: i64; mtp: Option<Mtp>; mixer: Vec<i64>; linears: Vec<Linear>; small: Vec<Vec<f32>>; gpu: Option<Gpu>; device: Vec<DeviceLinear>; deviceSmall: Vec<Buffer>; signs: Vec<Buffer>; files: FlashFiles; vision?: Vision; stages: Vec<Model>; npu?: NpuLlm.Model; }

A converted model, on the GPU that gizhw:gpu opens (GIZLANG_DEVICE) when there is one (device), else on the host (linears); the small tensors are on both. The embedding stays in the file: a step reads its tokens' rows. template is the chat layout ("chatml", "llama3" or ""), system the system turn it writes when a chat has none, think whether its assistant turn opens with a thinking block, calls whether it writes tool calls as <tool_call><function=NAME><parameter=P>...; efforts the instructions its template gives a thinking turn at low, medium and high reasoning effort ("": none); stops are the tokens that end a generation and sampling the model's own settings. mtp is the MTP layer on a GPU when the model has one, vision its vision tower when its folder has one (convertVision), stages the models of its later layers on other GPUs (loadAcross).

  • arch: M23.Arch
  • folder: string
  • tokenizer: M34.Tokenizer
  • stops: Vec<i64>
  • template: string
  • system: string
  • think: bool
  • calls: bool
  • efforts: Vec<string>
  • sampling: M23.Sampling
  • embed: gizlang_safetensors.Stored
  • layers: Vec<M23.Layer>
  • norm: i64
  • head: i64
  • mtp: _gizlang_sdk_core.Option<M23.Mtp>
  • mixer: Vec<i64>
  • linears: Vec<M23.Linear>
  • small: Vec<Vec<f32>>
  • gpu: _gizlang_sdk_core.Option<M10.Gpu>
  • device: Vec<M23.DeviceLinear>
  • deviceSmall: Vec<M10.Buffer>
  • signs: Vec<M10.Buffer>
  • files: M23.FlashFiles
  • vision: _gizlang_sdk_core.Option<M23.Vision>
  • stages: Vec<M23.Model>
  • npu: _gizlang_sdk_core.Option<M28.Model>

ChatTokens

gizlang
type ChatTokens = { tokens: Vec<i64>; mark: i64; head: i64; }

A chat's prompt as tokens (Model.chatPrompt), the mark of Engine.add (where its messages end, before the assistant's turn starts: the chat's next request starts with these messages, so its slot reads only the rest) and its head (where the system turn with the tools ends: the chats with the same system turn share its keys and values).

  • tokens: Vec<i64>
  • mark: i64
  • head: i64

Engine

gizlang
type Engine = { model: Model; slots: i64; context: i64; rows: i64; lengths: Vec<i64>; keys: Vec<Vec<f32>>; values: Vec<Vec<f32>>; convs: Vec<Vec<f32>>; states: Vec<Vec<f32>>; replay: Vec<Vec<f32>>; hidden: Vec<f32>; work: Vec<Buffer>; pages: Vec<Vec<i64>>; table: Vec<f32>; free: Vec<i64>; maxPages: i64; seen: Vec<string>; shapes: Vec<string>; recordings: Vec<G.Recording>; depth: i64; pending: Vec<i64>; drafts: i64; kept: i64; draftBlocks: Vec<i64>; blockEntry: Vec<i64>; nextEntry: i64; paces: Vec<f64>; stepNs: f64; rowNs: f64; kv: KvFormat; waiting: Vec<Turn>; turns: Vec<Turn>; next: Vec<i64>; guesses: Vec<Vec<Guess>>; held: Vec<Vec<i64>>; freed: Vec<i64>; saved: Vec<Saved>; pieces: Vec<bytes>; shared: Vec<Shared>; borrowed: Vec<i64>; stored: Vec<Prefix>; ids: i64; steps: i64; reuse: bool; flash: Flash; stages: Vec<Engine>; }

The engine of a model: slots sequences of at most context positions, steps of at most rows rows.

  • model: M23.Model
  • slots: i64
  • context: i64
  • rows: i64
  • lengths: Vec<i64>
  • keys: Vec<Vec<f32>>
  • values: Vec<Vec<f32>>
  • convs: Vec<Vec<f32>>
  • states: Vec<Vec<f32>>
  • replay: Vec<Vec<f32>>
  • hidden: Vec<f32>
  • work: Vec<M10.Buffer>
  • pages: Vec<Vec<i64>>
  • table: Vec<f32>
  • free: Vec<i64>
  • maxPages: i64
  • seen: Vec<string>
  • shapes: Vec<string>
  • recordings: Vec<M10.Recording>
  • depth: i64
  • pending: Vec<i64>
  • drafts: i64
  • kept: i64
  • draftBlocks: Vec<i64>
  • blockEntry: Vec<i64>
  • nextEntry: i64
  • paces: Vec<f64>
  • stepNs: f64
  • rowNs: f64
  • kv: M23.KvFormat
  • waiting: Vec<M23.Turn>
  • turns: Vec<M23.Turn>
  • next: Vec<i64>
  • guesses: Vec<Vec<M23.Guess>>
  • held: Vec<Vec<i64>>
  • freed: Vec<i64>
  • saved: Vec<M23.Saved>
  • pieces: Vec<bytes> — The bytes of each token (Tokenizer.tokenBytes), read at the first request with a grammar.
  • shared: Vec<M23.Shared>
  • borrowed: Vec<i64>
  • stored: Vec<M23.Prefix>
  • ids: i64
  • steps: i64
  • reuse: bool
  • flash: M23.Flash
  • stages: Vec<M23.Engine>

Visual

gizlang
type Visual = { rows: Vec<i64>; embeds: Vec<f32>; deep: Vec<Vec<f32>>; grid: Vec<i64>; }

Rows of a step that hold no token's embedding (Qwen3-VL's pictures): rows of the step, their embeddings (dim floats a row, in turn), deep the features added to them after each of the first layers (Qwen3-VL's deepstack, rows as embeds), and grid every row's three rotary positions (time, height, width; a text row's three are its position: see ropeTable).

  • rows: Vec<i64>
  • embeds: Vec<f32>
  • deep: Vec<Vec<f32>>
  • grid: Vec<i64>

KvFormat

gizlang
type KvFormat = { keys: i64; values: i64; }

How an engine keeps keys and values: the bits of a key and of a value. 16: F16 values; 8, 4 or 2: codes of the head rotated by blocks of kvBlock, at 2^bits even steps (kvStore).

  • keys: i64
  • values: i64

ExpertCache

gizlang
type ExpertCache = { slots: i64; hits: i64; misses: i64; readMs: f64; }

The expert cache of an engine: its slots, the experts found in it and read into it, and the ms the reads took.

  • slots: i64
  • hits: i64
  • misses: i64
  • readMs: f64

Guess

gizlang
type Guess = { token: i64; q: Dist; }

A draft per sequence: its token and the distribution it was drawn from (all on the token when it is the most likely).

  • token: i64
  • q: M23.Dist

Vision

gizlang
type Vision = { named: Map<string, Tensor>; gpu: Option<Gpu>; deep: Vec<i64>; depth: i64; width: i64; heads: i64; side: i64; }

A Qwen vision tower (loadVision): its weights by name where it runs (linears BF16, the rest f32; the patch embedding f32 [width, 768], the position table on the host), its blocks, width and heads, the side of its position table, and the blocks after which a deepstack merger reads the stream.

  • named: _gizlang_sdk_collections.Map<string, M32.Tensor>
  • gpu: _gizlang_sdk_core.Option<M10.Gpu>
  • deep: Vec<i64>
  • depth: i64
  • width: i64
  • heads: i64
  • side: i64

Stream

gizlang
type Stream = { ids: Vec<i64>; tags: Vec<i64>; grid: Vec<i64>; visual: Visual; shift: i64; }

A prompt as a language model with a vision tower reads it: its token ids, each with three rotary positions (grid: its index plus shift, which a picture's rows lower, as their grid is smaller than their count) and a tag of the caller's, and the pictures' rows (visual: the tower's rows at their places).

  • ids: Vec<i64>
  • tags: Vec<i64>
  • grid: Vec<i64>
  • visual: M23.Visual
  • shift: i64

Shown

gizlang
type Shown = { picture: Tensor; times: Vec<f64>; }

What a chat shows (Vision.chat): a picture ([3, h, w] f32 in [0, 1] on the host, h and w multiples of 32), or a video's frames ([n, 3, h, w]) with each frame's second in times.

  • picture: M32.Tensor
  • times: Vec<f64>

Seen

gizlang
type Seen = { chat: ChatTokens; visual: Visual; }

A chat's prompt with what it shows (Vision.chat): its tokens, mark and head, and the Visual of the whole prompt (Request.visual).

  • chat: M23.ChatTokens
  • visual: M23.Visual

Sampling

gizlang
type Sampling = { temperature: f64; topK: i64; topP: f64; seed: u64; presence?: f64; frequency?: f64; repetition?: f64; grammar?: Grammar; after?: i64; logprobs?: i64; }

How tokens are picked: temperature 0 the most likely, else one of the topK most likely (0: any) within topP of their probability, at temperature. Before that the logits are shaped, as OpenAI and vLLM shape them: less by presence for a token the answer has and by frequency for each time it has it; divided by repetition (above 0, times it below 0) for a token the prompt or the answer has. grammar: only the tokens it allows (gizml:grammar), from the token after after on (a reasoning model's end of thinking; none: from the first); a stop token only where the text is whole. logprobs: each token's log probability and the most likely ones (that many) are given, of the model's logits before shaping. A shaped request makes no drafts.

  • temperature: f64
  • topK: i64
  • topP: f64
  • seed: u64
  • presence: _gizlang_sdk_core.Option<f64>
  • frequency: _gizlang_sdk_core.Option<f64>
  • repetition: _gizlang_sdk_core.Option<f64>
  • grammar: _gizlang_sdk_core.Option<M22.Grammar>
  • after: _gizlang_sdk_core.Option<i64>
  • logprobs: _gizlang_sdk_core.Option<i64>

Dist

gizlang
type Dist = { ids: Vec<i64>; weights: Vec<f64>; }

What a sampled token is drawn from: tokens, most likely first, and their weights (a token's probability is its weight over their sum).

  • ids: Vec<i64>
  • weights: Vec<f64>

Request

gizlang
type Request = { prompt: Vec<i64>; limit: i64; sampling: Sampling; visual?: Visual; }

A prompt to continue: at most limit new tokens. With visual some of its rows are pictures' (Vision.chat): their embeddings replace their tokens', and its rows take their three rotary positions from visual.grid (three for each of its first rows, the last a text row's), the rows after them their position plus that last row's shift.

  • prompt: Vec<i64>
  • limit: i64
  • sampling: M23.Sampling
  • visual: _gizlang_sdk_core.Option<M23.Visual>

Logprob

gizlang
type Logprob = { token: i64; logprob: f64; top: Vec<i64>; tops: Vec<f64>; }

A token's log probability and the top most likely tokens with theirs, of the model's logits.

  • token: i64
  • logprob: f64
  • top: Vec<i64>
  • tops: Vec<f64>

Progress

gizlang
type Progress = { id: i64; tokens: Vec<i64>; cached: i64; end: string; logprobs: Vec<Logprob>; }

What a step gave a request (Engine.advance): its new tokens (without a stop token), the tokens at the start of its prompt that its slot held already (not read again), and why it ended: "stop" (a stop token), "length" (its limit, the context's end, or a KV cache too small for it alone) or "" (it goes on).

  • id: i64
  • tokens: Vec<i64>
  • cached: i64
  • end: string
  • logprobs: Vec<M23.Logprob>

Turn

gizlang
type Turn = { id: i64; request: Request; random: Vec<u64>; made: i64; mark: i64; head: i64; cached: i64; reading?: Recognizer; }

A request in an engine's turn: its id, its random state, the tokens it gave, the prompt position after which its slot saves the recurrent states (Engine.add), the position after which its prompt's start is shared (Engine.add; 0: none), the prompt tokens its slot held already and its grammar's recognizer while the grammar holds (Sampling).

  • id: i64
  • request: M23.Request
  • random: Vec<u64>
  • made: i64
  • mark: i64
  • head: i64
  • cached: i64
  • reading: _gizlang_sdk_core.Option<M22.Recognizer>

Saved

gizlang
type Saved = { at: i64; conv: Vec<f32>; state: Vec<f32>; }

A slot's recurrent states after its first at tokens (0: none): the convolutions' last inputs and the delta rules' states, on the host (from a GPU the states' BF16, two to a float).

  • at: i64
  • conv: Vec<f32>
  • state: Vec<f32>

Prefix

gizlang
type Prefix = { tokens: Vec<i64>; saved: Saved; pages: Vec<bytes>; keys: Vec<Vec<f32>>; values: Vec<Vec<f32>>; used: i64; stages: Vec<Prefix>; }

The start of a chat that left its slot for another (see admit): its tokens, the recurrent states after them, and their keys and values (on a GPU the bytes of their KV pages, on the host per pool layer); used is the step it was stored at. A later prompt that starts with the tokens takes them back into a slot and reads only the rest. On a model in stages, stages holds each later stage's pages and states (Engine.stages).

  • tokens: Vec<i64>
  • saved: M23.Saved
  • pages: Vec<bytes>
  • keys: Vec<Vec<f32>>
  • values: Vec<Vec<f32>>
  • used: i64
  • stages: Vec<M23.Prefix>

Shared

gizlang
type Shared = { tokens: Vec<i64>; saved: Saved; pages: Vec<i64>; keys: Vec<Vec<f32>>; values: Vec<Vec<f32>>; used: i64; stages: Vec<Shared>; }

A start that many prompts share (as the system turn and tools of an agent's chats, Model.chatTokens): its tokens (whole KV pages), the recurrent states after them, and their keys and values: on a GPU the KV pages of the pool that hold them, which the slots that start with them read in place (Engine.borrowed), on the host a copy per pool layer; used is the step a slot last took it. On a model in stages, stages holds each later stage's pages and states.

  • tokens: Vec<i64>
  • saved: M23.Saved
  • pages: Vec<i64>
  • keys: Vec<Vec<f32>>
  • values: Vec<Vec<f32>>
  • used: i64
  • stages: Vec<M23.Shared>

BertConfig

gizlang
type BertConfig = { kind: string; layers: i64; heads: i64; dim: i64; eps: f64; act: string; positions: i64; offset: i64; }

A BERT-family encoder as a Hugging Face config.json gives it: BERT, RoBERTa and XLM-RoBERTa have one layout and differ in where positions start (offset: 0 for BERT, pad_token_id + 1 for RoBERTa). act is hidden_act: "gelu" (the erf form), "relu" or a tanh form ("gelu_new", "gelu_pytorch_tanh").

  • kind: string
  • layers: i64
  • heads: i64
  • dim: i64
  • eps: f64
  • act: string
  • positions: i64
  • offset: i64

ModelFiles

gizlang
type ModelFiles = (path: string) => Result<Option<bytes>, string>

Reads the file at a path of a model's repository: none when the model has no such file.

Encoder

gizlang
type Encoder = { config: BertConfig; weights: Map<string, Tensor>; tokenizer: Tokenizer; pooling: string; normalize: bool; limit: i64; }

A sentence encoder as sentence-transformers 3 builds it from a model's files: an encoder, then the pooling of its token states ("mean", "cls", "max", "mean_sqrt_len" or "last"), then L2 normalization when the model has that module.

  • config: M23.BertConfig
  • weights: _gizlang_sdk_collections.Map<string, M32.Tensor>
  • tokenizer: M34.Tokenizer
  • pooling: string
  • normalize: bool
  • limit: i64

CrossEncoder

gizlang
type CrossEncoder = { config: BertConfig; weights: Map<string, Tensor>; tokenizer: Tokenizer; head: string; labels: i64; activation: string; limit: i64; }

A cross-encoder as sentence-transformers' CrossEncoder builds it: a sequence classification model that reads a pair of texts (a query and a document) and gives the scores of its labels. head is "bert" (BertForSequence- Classification: the pooler's tanh on the first token, then the classifier) or "roberta" (RobertaFor- and XLMRobertaForSequenceClassification: classifier.dense, tanh, classifier.out_proj). activation is the function on the scores: "sigmoid" (the default with one label), "identity" (the default with more) or "tanh".

  • config: M23.BertConfig
  • weights: _gizlang_sdk_collections.Map<string, M32.Tensor>
  • tokenizer: M34.Tokenizer
  • head: string
  • labels: i64
  • activation: string
  • limit: i64

Ranked

gizlang
type Ranked = { corpus: i64; score: f64; }

A document of a ranking: its index in the documents and its score.

  • corpus: i64
  • score: f64

Functions

archOf

gizlang
function archOf(config: JsonValue): Arch throws string

The Arch of a model by its config.json; an error names what this module does not run yet.

Effects: fail.

convert

gizlang
function convert(sys: System, from: string, to: string, bits: Bits, layers: i64 = 0, lora: string = ""): i64 throws string

Converts the Hugging Face model in folder from (config.json, safetensors, tokenizer), or the GGUF file from (gizlang:gguf: Llama, Qwen2 and Qwen3, its block types read as they are; the embedding keeps its block type), to this module's format in folder to: model.safetensors with every linear quantized (see Quantization), the norms and small tensors as f32 and the embedding as its source holds it, with the source's config, tokenizer and generation files. With layers less than the model's, only its first layers layers, without the final norm, the head and the MTP layer (a source cut after them, as MiniMax H3's text encoder, holds no more): load it with the same layers. A cut Qwen3.8 Flash keeps its mixer and head (a test of its first layers). A vision tower (model.visual.*) goes to visual.safetensors (convertVision). Returns the bytes written. With lora, the PEFT LoRA adapter in that folder (adapter_config.json, adapter_model.safetensors) is merged into the linears it adapts before they are quantized: W + alpha / r B A (alpha / sqrt(r) with rsLoRA).

Effects: fail, read, write, console, io.

load

gizlang
function load(sys: System, folder: string, onGpu: bool = true, layers: i64 = 0): Model throws string

The converted model in folder, on the GPU when onGpu and there is one, and across the driver's other GPUs too when its weights do not leave SPLIT_ROOM free on that one (loadAcross). With layers less than the model's, only its first layers layers, without the final norm, the head and the MTP layer: an engine of it gives hidden states (Engine.hidden), not logits. A gizml:npullm folder (model.q4nx) runs on this host's NPU (Model.npu).

Effects: fail, read, write, console, io.

loadAcross

gizlang
function loadAcross(sys: System, folder: string, gpus: Vec<Gpu>, counts: Vec<i64> = []): Model throws string

The converted model in folder across gpus (Gpu.others), in stages of consecutive layers: the first GPU holds the first stage (and the vision tower), the last the last stage with the final norm and the head (Model.stages). A stage's layer count is counts[i], by default in proportion to its GPU's free memory. A step runs the stages in turn, each on its rows' hidden states after the one before (Engine). Without the MTP layer, and not for Qwen3.8 Flash yet. The first GPU is current at the end.

Effects: fail, read, write, console, io.

loadOn

gizlang
function loadOn(sys: System, folder: string, gpu: Option<Gpu>, layers: i64 = 0, from: i64 = 0, streamed: bool = false): Result<Model, string>

load on the GPU gpu (none: the host). With from, the layers layers from layer from on (a stage of loadAcross): the norm, the head and the MTP layer only where they are the model's last. streamed: the vision tower's linears stay in host memory (loadVision).

Effects: fail, read, write, console, io.

converted

gizlang
function converted(hub: Hub.Hub, repo: string, folder: string, bits: Bits, layers: i64 = 0): string throws string

The folder of the model in folder folder ("" for its top) of Hugging Face repository repo ("Qwen/Qwen3.5-4B") converted with bits (and layers, as convert cuts), for load with the same layers: the folder is downloaded through hub once (Hub.snapshot) and converted once into .gizlang-llm/REPO[/FOLDER]/BITS in the hub's folder. A conversion is written to a partial folder and renamed when it is complete, so a stopped one is done again, never loaded.

Effects: fail, read, write, console, io.

convertedFolder

gizlang
function convertedFolder(hub: Hub.Hub, repo: string, folder: string, bits: Bits, layers: i64 = 0): string

Where converted puts a conversion; the folder holds model.safetensors once the conversion is complete.

Effects: fail.

toolCalls

gizlang
function toolCalls(text: string, tools: Vec<JsonValue>, first: i64 = 0): Vec<Hub.Call>

The tool calls in the text a model wrote after its answer (Model.calls: <tool_call><function=NAME><parameter=P> VALUE</parameter>...), each value as JSON by the type its tool gives the parameter: a string stays text, another type is read as JSON (text when it is not). Their ids are call_FIRST_K.

Effects: fail.

kvFormat

gizlang
function kvFormat(name: string): KvFormat throws string

The format a name gives: BITS for keys and values, or KEYS/VALUES ("4/2"); "" is the engine's choice (keys 0).

Effects: fail.

kvName

gizlang
function kvName(f: KvFormat): string

The name of a format, as kvFormat reads it.

Effects: fail.

convertVision

gizlang
function convertVision(sys: System, stored: Vec<Stored>, config: JsonValue, to: string): i64 throws string

Writes the vision tower of the Hugging Face folder from (model.visual.*, as stored) to to/visual.safetensors, with its heads and deepstack blocks (config.json's vision_config) in the header; returns its bytes.

Effects: fail, io.

hasVision

gizlang
function hasVision(sys: System, folder: string): bool

Whether folder holds a vision tower (convertVision's).

Effects: fail, io.

loadVision

gizlang
function loadVision(sys: System, folder: string, gpu: Option<Gpu>, streamed: bool = false): Vision throws string

The vision tower of folder/visual.safetensors (convertVision's) on gpu when there is one. A file of format 1 (before 10/22: Qwen3-VL-32B's for H3, Qwen3.5-9B's for FLUX.3's upsampler) has 16 heads, and its deepstack mergers read blocks 8, 16 and 24. With streamed, its linears' weights stay in host memory and a pass uploads each as it reads it (Vision.w): the card keeps their bytes free between pictures, and a pass moves them over the bus.

Effects: fail, read, write, console, io.

stream

gizlang
function stream(deep: i64): Stream

An empty stream whose pictures keep deep deepstack features each (Vision.seen).

Effects: fail.

visionSize

gizlang
function visionSize(width: i64, height: i64, least: i64, most: i64): Vec<i64>

The size [w, h] at which Qwen's processors show a picture of width x height (smart_resize): each side a multiple of 32 (2 x 2 patches of 16), the area from least to most pixels, the aspect kept as near as they allow.

Effects: fail.

greedy

gizlang
function greedy(): Sampling

The most likely token at each step: the same tokens on each run.

pick

gizlang
function pick(logits: Vec<f32>, at: i64, vocab: i64, s: Sampling, state: mut Vec<u64>): i64

A token from logits[at, at + vocab); state holds the random state.

Effects: fail.

bertWeights

gizlang
function bertWeights(tensors: Vec<Named>): Map<string, Tensor>

The tensors of a BertModel or RobertaModel checkpoint by their names, without the "bert." or "roberta." prefix of a task model, and with LayerNorm.gamma and beta (older checkpoints) as weight and bias.

Effects: fail.

bert

gizlang
function bert(c: BertConfig, w: Map<string, Tensor>, ids: Vec<i64>, types: Vec<i64>, sequences: i64): Tensor throws string

The last hidden states (sequences tokens, dim) of the encoder for sequences sequences of one length: their token ids and token types one sequence after another, every token attended (no padding). The weights may be on a GPU (Encoder.on); the states are where the weights are.

Effects: fail, read, write, console, io.

encoderOf

gizlang
function encoderOf(files: ModelFiles): Encoder throws string

The encoder of a model by the files it reads from its repository: config.json, tokenizer.json, model.safetensors and, for a sentence-transformers model, modules.json, sentence_bert_config.json and the pooling module's config.json. Without modules.json the tokens are mean-pooled and not normalized, as sentence-transformers does.

Effects: fail, read, write, console, io.

crossEncoderOf

gizlang
function crossEncoderOf(files: ModelFiles): CrossEncoder throws string

The cross-encoder of a model by its repository's files: config.json (its sentence_transformers.activation_fn, when present, names the activation), tokenizer.json and model.safetensors.

Effects: fail, read, write, console, io.

Methods

Arch.qRows

gizlang
function Arch.qRows(self: Arch): i64

Values of a query (and of its output gate when the model has one) per token.

Effects: fail.

Arch.qkvRows

gizlang
function Arch.qkvRows(self: Arch): i64

Rows of the fused q, k, v projection.

Effects: fail.

Arch.convDim

gizlang
function Arch.convDim(self: Arch): i64

Channels of a recurrent layer's convolution: q, k and v.

Effects: fail.

Arch.inRows

gizlang
function Arch.inRows(self: Arch): i64

Rows of a recurrent layer's fused input projection: q, k, v, the gate z, then b and a (one a value head).

Effects: fail.

Model.chatPrompt

gizlang
function Model.chatPrompt(self: Model, messages: Vec<Message>, thinking: bool, tools: Vec<JsonValue> = [], effort: string = "high"): string

The prompt of a chat as the model's template writes it, ending with the start of the assistant's turn (with an empty thinking block unless thinking), a thinking turn with the instruction of its reasoning effort (low, medium or high: Model.efforts), and the tools it may call (OpenAI's tool objects, for a model whose template writes tool calls: Model.calls).

Effects: fail.

Model.chatTokens

gizlang
function Model.chatTokens(self: Model, messages: Vec<Message>, thinking: bool, tools: Vec<JsonValue> = [], effort: string = "high"): ChatTokens

The tokens of messages in the model's chat template, up to where the assistant's turn starts (ChatTokens).

Effects: fail.

Model.engine

gizlang
function Model.engine(self: Model, slots: i64, context: i64, reserve: i64 = 134_217_728, drafts: i64 = 3, rows: i64 = 0, kv: string = ""): Result<Engine, string>

An engine for slots sequences of up to context positions, reading up to rows rows a step (0: 256; at least 1 + drafts rows a slot, 2 without drafts). On a GPU the KV pages take the device memory left after the work buffers and recurrent states, at most what the slots can hold, keeping reserve bytes free. Keys and values take the format kv names (kvFormat; F16 where the heads take no codes, see kvWidth), by default the first of kvFormats in which the slots' whole contexts fit above 4 bits, or one whole context at most 4 bits, else the last (on the host 8 bits). An engine reads up to drafts drafts a sequence and step (0: none; 3 is DRAFTS), and with the model's MTP layer Engine.advance drafts them where that gives tokens faster (EXPLORE), on a GPU or the host (where 1 draft is the fastest: its 4-bit layers take two rows in the time of one, and each further draft costs a step of the MTP layer).

Effects: fail, read, write, console, io.

Engine.reset

gizlang
function Engine.reset(self: mut Engine, slot: i64): void

Empties a slot for a new sequence.

Effects: fail, read, write, console, io.

Engine.length

gizlang
function Engine.length(self: Engine, slot: i64): i64

Positions held by a slot.

Effects: fail.

Engine.step

gizlang
function Engine.step(self: mut Engine, sys: System, tokens: Vec<i64>, slots: Vec<i64>, wanted: Vec<i64>, drafts: Vec<i64> = [], visual: Option<Visual> = undefined): Vec<f32> throws string

Reads tokens into their slots (the rows of a slot together and in order, after what the slot holds) and returns the logits of the rows wanted (vocab floats each, in that order). On an engine that drafts (Engine.depth), a slot's last drafts[slot] rows (none when drafts is empty) are drafts of the tokens after its row before them: they wait for Engine.accept, which the slot's next step needs first. With visual, some rows are a picture's (Visual, as Engine.hidden), and every row takes its three rotary positions from it.

Effects: fail, read, write, console, io.

Engine.accept

gizlang
function Engine.accept(self: mut Engine, slot: i64, kept: i64): bool throws string

Keeps the first kept of a slot's drafts of its last step and drops the others.

Effects: fail, read, write, console, io.

Engine.hidden

gizlang
function Engine.hidden(self: mut Engine, sys: System, tokens: Vec<i64>, slots: Vec<i64>, layers: Vec<i64> = [], visual: Option<Visual> = undefined): Vec<f32> throws string

Reads tokens into their slots as Engine.step does and returns the residual stream of each row after each of layers (counted from 1; none: the model's last), dim floats a row and layer: Hugging Face's hidden_states[l] for each l, before the final norm (Hugging Face norms the whole model's last hidden state). With visual, some rows are a picture's (Visual), not their tokens' embeddings.

Effects: fail, read, write, console, io.

Engine.padding

gizlang
function Engine.padding(self: mut Engine, sys: System, slot: i64, token: i64, position: i64, layers: Vec<i64> = []): Vec<f32> throws string

The hidden states (as Engine.hidden) of one row of token at rotary position position that sees the keys of the slot's tokens but not its own, and leaves the slot as it was: a padding row of a Hugging Face batch, whose mask hides the padding keys from every row. Every padding row of a sequence is this one row (FLUX.3 reads Qwen3-VL's, at position 1). Models of attention layers only.

Effects: fail, read, write, console, io.

Engine.expertCache

gizlang
function Engine.expertCache(self: Engine): ExpertCache

The expert cache counts of the engine.

Vision.seen

gizlang
function Vision.seen(self: Vision, picture: Tensor, later: Vec<Tensor> = []): Vec<Tensor>

The vision tower's rows of a picture ([3, h, w] f32 in [0, 1] on the host, h and w multiples of 32): its merged rows ([h w / 1024, the language model's width]) and the deepstack features after each of its deep blocks (rows as the merged), f32 on the host. A video's pair of frames is picture and later (one frame).

Effects: fail, read, write, console, io.

Stream.words

gizlang
function Stream.words(self: mut Stream, tokens: Vec<i64>, tag: i64): void

The tokens tokens of tag.

Effects: fail.

Stream.picture

gizlang
function Stream.picture(self: mut Stream, vision: Vision, picture: Tensor, start: i64, pad: i64, end: i64, later: Vec<Tensor> = []): void

Picture ([3, h, w] f32 in [0, 1] on the host, h and w multiples of 32) as vision reads it: the token start, a pad token for each row of the tower's merged rows (on the rotary positions of its grid), then end. A video's pair of frames is picture and later (one frame; the tower's temporal patch of two).

Effects: fail, read, write, console, io.

Stream.video

gizlang
function Stream.video(self: mut Stream, vision: Vision, tok: Tokenizer, clip: Tensor, times: Vec<f64>, start: i64, pad: i64, end: i64, tag: i64): bool throws string

A video ([n, 3, h, w] f32 in [0, 1] on the host, h and w multiples of 32; times: each frame's second) as Qwen3-VL reads it: its frames in pairs (the last repeated when n is odd), each pair the text "<t seconds>" (tok's tokens, of tag; t the second of its middle) and then the pair as Stream.picture shows it.

Effects: fail, read, write, console, io.

Stream.part

gizlang
function Stream.part(self: Stream, at: i64, end: i64, dim: i64): Option<Visual>

The pictures' rows that fall in tokens at to end, as the step over them takes them (rows dim wide), or none when there are no pictures.

Effects: fail.

Vision.chat

gizlang
function Vision.chat(self: Vision, tok: Tokenizer, chat: ChatTokens, shown: Vec<Shown>): Seen throws string

The prompt chat (Model.chatTokens) with what it shows: in its text each picture is Qwen's "<|vision_start|><|image_pad|><|vision_end|>" and each video "<|vision_start|><|video_pad|><|vision_end|>", in the order of shown; each becomes the tower's rows (Stream.picture, Stream.video), and the mark and head move past the rows before them.

Effects: fail, read, write, console, io.

Engine.generate

gizlang
function Engine.generate(self: mut Engine, sys: System, requests: Vec<Request>): Vec<Vec<i64>> throws string

Generates for every request and returns each one's new tokens (without the stop token): Engine.add of each, then Engine.advance until none is in turn.

Effects: fail, read, write, console, io.

Engine.warm

gizlang
function Engine.warm(self: mut Engine, sys: System): bool throws string

Runs once each kind of step a server meets first: a long prompt read in parts, then 1 to slots sequences that read a prompt and write tokens. The first run of a step shape compiles, tunes and records its kernels (seconds for a large model), so a server warms before it takes requests.

Effects: fail, read, write, console, io.

Engine.add

gizlang
function Engine.add(self: mut Engine, request0: Request, mark: i64 = 0, head: i64 = 0): i64 throws string

Puts a request in turn and returns its id, which Engine.advance's results name. A free slot that holds the start of its prompt (an earlier request's prompt and answer) takes it and reads only the rest; so does a slot that takes back such a start from the host, where a slot keeps what it held when another request takes it (Prefix). After mark tokens of the prompt (0: none) its slot also keeps the recurrent states, so a later prompt that starts with those tokens but not with all the slot read reads only the rest too; for a chat that is where its messages end (Model.chatTokens). The prompt's first head tokens (0: none; for a chat its system turn with the tools), cut to whole KV pages and when at least SHARED_MIN, become a start that later prompts share (Shared): a slot whose prompt starts with it reads only the rest, and on a GPU all such slots read one copy of its keys and values.

Effects: fail.

Engine.cancel

gizlang
function Engine.cancel(self: mut Engine, id: i64): bool

Takes a request out of turn; false when it is not in turn (it ended). Its slot keeps what it read.

Effects: fail.

Engine.busy

gizlang
function Engine.busy(self: Engine): bool

Whether requests are in turn.

Effects: fail.

Engine.advance

gizlang
function Engine.advance(self: mut Engine, sys: System): Vec<Progress> throws string

One step of the requests in turn, and what each gained. First free slots take waiting requests (Engine.add). The step reads the next token of every generating sequence and, in the rows left, the next piece of the prompts not read yet. When the KV pool has no room for the step, a free slot gives its pages, else the request that came last waits again from where it is (its prompt and answer so far).

A drafting engine (Engine.depth) also reads each generating sequence's drafts of the tokens after that: each row judges the draft after it (kept when it is the token picked; when sampling, kept with its probability and otherwise a token other than it is picked, which gives the same distribution as without drafts) up to the first rejected, and when all are kept the last row gives one more token, so a step reading weights once can give 1 + depth tokens. The step reads them as drafts (Engine.step) and keeps those judged right (Engine.accept). Then the MTP layer reads every row kept, with the token after it, and where drafts gave tokens faster for as many generating sequences (EXPLORE), drafts after each sequence's last; it reads each draft again, with its own hidden state for it, for the next.

Effects: fail, read, write, console, io.

Engine.complete

gizlang
function Engine.complete(self: mut Engine, sys: System, prompt: string, limit: i64, s: Sampling): string throws string

The text the model writes after prompt (special tokens in it read as such), at most limit tokens.

Effects: fail, read, write, console, io.

Encoder.on

gizlang
function Encoder.on(self: Encoder, gpu: Gpu): Encoder

The encoder with its weights on gpu: it encodes there and gives the same embeddings to f32 precision.

Effects: fail, read, write, console, io.

Encoder.embed

gizlang
function Encoder.embed(self: Encoder, text: string, normalize: bool): Vec<f64> throws string

The embedding of a text (Encoder.embedBatch of one).

Effects: fail, read, write, console, io.

Encoder.embedBatch

gizlang
function Encoder.embedBatch(self: Encoder, texts: Vec<string>, normalize: bool, batch: i64): Vec<Vec<f64>> throws string

The embeddings of texts: their token states pooled and, when the model says so or normalize, of length 1. The texts of one token count go through the encoder together, at most batch of them at a time, so no token is padding.

Effects: fail, read, write, console, io.

CrossEncoder.on

gizlang
function CrossEncoder.on(self: CrossEncoder, gpu: Gpu): CrossEncoder

The cross-encoder with its weights on gpu.

Effects: fail, read, write, console, io.

CrossEncoder.scores

gizlang
function CrossEncoder.scores(self: CrossEncoder, query: string, documents: Vec<string>, batch: i64): Vec<Vec<f64>> throws string

The scores of the labels of each pair (query, documents[i]), after the activation: CrossEncoder.predict. The pairs of one token count go through the encoder together, at most batch at a time.

Effects: fail, read, write, console, io.

CrossEncoder.rank

gizlang
function CrossEncoder.rank(self: CrossEncoder, query: string, documents: Vec<string>, top: i64, batch: i64): Vec<Ranked> throws string

The documents by the score of (query, document), the highest first, at most top of them (0: all): CrossEncoder. rank. Equal scores keep the documents' order. The model must have one label.

Effects: fail, read, write, console, io.

Constants

ATTENTION

gizlang
const ATTENTION = 0

A layer of softmax attention over a KV cache.

RECURRENT

gizlang
const RECURRENT = 1

A layer of gated delta-rule linear attention over a recurrent state.

CALL

gizlang
const CALL = "<tool_call>"

Where a model that writes tool calls (Model.calls) starts them.

DRAFTS

gizlang
const DRAFTS = 3

The tokens an engine drafts per sequence and step by default: the n-th draft is kept less often than the one before, and each costs a step of the MTP layer and the head.