{"protocolVersion":3,"opsHash":"e5b95b9b693abafe","conventions":["Tensors are row-major f32. Ops that speak of rows and columns fold every leading dimension into rows, so [batch, seq, channels] behaves as [batch*seq, channels] with no reshape.","Weights as stored in a checkpoint ([out, in]) are used directly: pass transB: true to matmul and linear; embedding and moe read them as stored.","Put as many ops as possible into one graph. Intermediates stay on the volunteer, so a whole decoder layer — or a whole decode step — costs one round trip.","A parameter listed under \"features\" is an optional capability. A step using one is only routed to workers that implement it; if none is connected the graph is refused with the feature named.","Integer inputs (token ids, positions) are f32 values holding integers, which is exact for every vocabulary size in use."],"ops":[{"op":"add","summary":"Elementwise a + b.","inputs":["a","b — same shape as a, a row vector as wide as a, or a single value"],"output":"same shape as the input","minInputs":2,"maxInputs":2,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"argmax","summary":"Index of the maximum over the last axis, ties to the lowest index. Choose tokens on the device rather than returning logits.","inputs":["x [..., N]"],"output":"[...] (or [1])","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"attention","summary":"Scaled dot-product attention with grouped-query support. q, k and v are flat — do not reshape into heads. The score matrix never leaves the worker.","inputs":["q [T, heads*headDim]","k [S, kvHeads*headDim]","v [S, kvHeads*vHeadDim]","optional bias [T, S] or [heads, T, S], added to the scores (use -1e9 to mask)"],"output":"[T, heads*vHeadDim]","minInputs":3,"maxInputs":4,"params":{"heads":{"type":"number","description":"num_attention_heads"},"headDim":{"type":"number","description":"query/key width per head"},"kvHeads":{"type":"number?","description":"num_key_value_heads; defaults to heads"},"vHeadDim":{"type":"number?","description":"value width per head when it differs from headDim (DeepSeek MLA)"},"causal":{"type":"boolean?","description":"default true"},"posOffset":{"type":"number?","description":"absolute position of the first query row; with a KV cache, the current position"},"scale":{"type":"number?","description":"replaces 1/sqrt(headDim): query_pre_attn_scalar^-0.5 for Gemma 2/3, attention_multiplier for Granite"},"softcap":{"type":"number?","description":"attn_logit_softcapping (Gemma 2)"},"window":{"type":"number?","description":"sliding_window: causal keys visible when pos - window < s <= pos; non-causal when |pos - s| <= window"},"alibi":{"type":"boolean?","description":"true for BLOOM ALiBi slopes"},"alibiMax":{"type":"number?","description":"MPT ALiBi with alibi_bias_max (usually 8)"},"alibiSlopes":{"type":"array?","description":"explicit per-head ALiBi slopes"}},"features":["attention.alibi","attention.bias","attention.scale","attention.softcap","attention.window"],"addedIn":"v3","core":false},{"op":"cache_write","summary":"Write rows into a preallocated cache in place and return the cache. The KV cache op: a session keeps pointing at the same tensor, so no retain is needed.","inputs":["cache [maxRows, width]","values [rows, width]"],"output":"the cache","minInputs":2,"maxInputs":2,"params":{"offset":{"type":"number","description":"row to start writing at — the current position"}},"features":[],"mutatesInput":0,"addedIn":"v3","core":false},{"op":"causal_mask","summary":"Set the strict upper triangle of each square block of the last two dims to -inf.","inputs":["a [..., n, n]"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":false},{"op":"concat","summary":"Join along the leading axis or the last one.","inputs":["a","b"],"output":"a with the chosen axis extended","minInputs":2,"maxInputs":2,"params":{"axis":{"type":"number?","description":"0 (default) or the last axis; -1 means the last"}},"features":[],"addedIn":"v3","core":false},{"op":"conv1d","summary":"Depthwise causal 1-D convolution over a carried state. Pure: carry the state with slice + concat + cache_write in the same graph.","inputs":["x [T, C]","weight [C, 1, K]","state [K-1, C] — the rows immediately before x"],"output":"[T, C]","minInputs":3,"maxInputs":3,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"embedding","summary":"Row lookup. Out-of-range ids produce a zero row.","inputs":["ids [T] (integers as f32)","table [V, C] — usable packed, as stored"],"output":"[T, C]","minInputs":2,"maxInputs":2,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"geglu","summary":"gelu(gate) * up, tanh GELU — the Gemma feed-forward gate.","inputs":["gate","up — same shape"],"output":"same shape as the input","minInputs":2,"maxInputs":2,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"gelu","summary":"GELU, tanh approximation — HF \"gelu_new\" and \"gelu_pytorch_tanh\" (GPT-2, Phi-2, Gemma). For HF \"gelu\" use gelu_exact.","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"gelu_exact","summary":"GELU with erf — HF \"gelu\" (BERT, Falcon, GPT-NeoX/Pythia).","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"gelu_quick","summary":"x * sigmoid(1.702 x) — HF \"quick_gelu\" (CLIP).","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"layernorm","summary":"LayerNorm over the last dimension.","inputs":["x [..., C]","gamma [C]","beta [C] — use a zeros op for a bias-free LayerNorm"],"output":"same shape as the input","minInputs":3,"maxInputs":3,"params":{"eps":{"type":"number?","description":"default 1e-5; layer_norm_eps from config.json (BERT uses 1e-12)"}},"features":["layernorm.eps"],"addedIn":"v2","core":true},{"op":"linear","summary":"x · w + bias, fused.","inputs":["x [..., K]","w [K, N] — or [N, K] with transB","bias [N]"],"output":"[..., N]","minInputs":3,"maxInputs":3,"params":{"transB":{"type":"boolean?","description":"as for matmul"}},"features":[],"addedIn":"v2","core":true},{"op":"matmul","summary":"Matrix product.","inputs":["a [..., K]","b [K, N] — or [N, K] with transB"],"output":"[..., N]","minInputs":2,"maxInputs":2,"params":{"transB":{"type":"boolean?","description":"read b as [out, in], the layout checkpoints use; avoids a transposed copy of the weight"}},"features":[],"addedIn":"v2","core":true},{"op":"moe","summary":"A sparse mixture-of-experts feed-forward: route each token to topK experts, run only those, and sum their outputs weighted by the router. Shared experts are ordinary feed-forwards beside it.","inputs":["x [T, C]","router logits [T, E] — e.g. matmul(x, gate.weight, transB)","selection bias [E] — only with selectionBias","expert weights as stored: separate = gate_e [I,C], up_e [I,C], down_e [C,I] for e = 0..E-1; fused = gate_up [E,2I,C], down [E,C,I]; stacked = gate [E,I,C], up [E,I,C], down [E,C,I]"],"output":"[T, C]","minInputs":2,"maxInputs":1539,"params":{"topK":{"type":"number","description":"num_experts_per_tok"},"scoring":{"type":"string?","description":"\"softmax\" (default: Mixtral, Qwen-MoE, OLMoE) or \"sigmoid\" (DeepSeek-V3)"},"normalize":{"type":"boolean?","description":"renormalise the chosen weights to sum to 1 — Mixtral always; Qwen norm_topk_prob"},"scale":{"type":"number?","description":"routed_scaling_factor; default 1"},"nGroup":{"type":"number?","description":"n_group for group-limited routing (DeepSeek)"},"topKGroup":{"type":"number?","description":"topk_group"},"groupTopK":{"type":"number?","description":"how many of a group's best scores make its group score; default 1 (the maximum). transformers 5.17's DeepSeek-V3 router sums the best 2"},"selectionBias":{"type":"boolean?","description":"true when a bias input follows the logits (DeepSeek-V3 e_score_correction_bias): it affects which experts are chosen, not their weights"},"layout":{"type":"string?","description":"\"separate\" (default), \"fused\" or \"stacked\" — see inputs"},"activation":{"type":"string?","description":"\"silu\" (default, SwiGLU experts) or \"gelu\" (GeGLU experts)"}},"features":[],"addedIn":"v3","core":false},{"op":"mul","summary":"Elementwise a * b.","inputs":["a","b — broadcast as for add"],"output":"same shape as the input","minInputs":2,"maxInputs":2,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"reduce_max","summary":"Maximum over the last axis, one per row.","inputs":["x [..., N]"],"output":"[...] (or [1])","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"reduce_mean","summary":"Mean of every element.","inputs":["x"],"output":"[1]","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"reduce_sum","summary":"Sum of every element.","inputs":["x"],"output":"[1]","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"relu","summary":"max(x, 0).","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"reshape","summary":"Same values, new shape.","inputs":["a"],"output":"params.shape","minInputs":1,"maxInputs":1,"params":{"shape":{"type":"array","description":"the new shape; element count must match"}},"features":[],"addedIn":"v3","core":false},{"op":"rmsnorm","summary":"RMSNorm over the last dimension.","inputs":["x [..., C]","gamma [C], or [groupSize] with groupSize"],"output":"same shape as the input","minInputs":2,"maxInputs":2,"params":{"eps":{"type":"number?","description":"default 1e-6; rms_norm_eps from config.json"},"weightOffset":{"type":"number?","description":"multiply by (gamma + weightOffset). Gemma stores norm weights as offsets from 1: pass 1"},"groupSize":{"type":"number?","description":"normalise every groupSize channels separately — per-head q/k norm (Qwen3, Gemma 3) with groupSize = head_dim and no reshape"}},"features":["rmsnorm.groupSize","rmsnorm.weightOffset"],"addedIn":"v3","core":false},{"op":"rope","summary":"Rotary position embedding over [tokens, heads*headDim].","inputs":["x [T, heads*headDim]"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{"headDim":{"type":"number","description":"per-head width"},"base":{"type":"number?","description":"rope_theta; default 10000"},"offset":{"type":"number?","description":"absolute position of the first row — the current position when decoding"},"rotaryDim":{"type":"number?","description":"rotate only the first rotaryDim channels of each head (partial_rotary_factor * head_dim, or GPT-J rotary_dim); the rest pass through"},"interleaved":{"type":"boolean?","description":"pair channels (2i, 2i+1) instead of (i, i + rotaryDim/2) — GPT-J, CodeGen, Cohere, GLM; false (half-split) is Llama/Qwen/Mistral/NeoX"},"scaling":{"type":"object?","description":"rope_scaling / rope_parameters from config.json, as-is: linear, llama3 (Llama 3.1+), yarn, longrope, dynamic. For longrope also pass max_position_embeddings unless attention_factor is given"},"invFreq":{"type":"array?","description":"explicit inverse frequencies, rotaryDim/2 of them, for any scheme not covered by scaling"},"attentionFactor":{"type":"number?","description":"multiplies cos and sin; yarn and longrope derive it when omitted"}},"features":["rope.interleaved","rope.rotaryDim","rope.scaling"],"addedIn":"v3","core":false},{"op":"sample","summary":"Draw a token per row from logits. temperature 0 is exactly argmax. Deterministic for a given (seed, step).","inputs":["logits [..., V]","history [N] or [N, 1] — optional token ids to penalise (negative = empty slot)"],"output":"[...] (or [1])","minInputs":1,"maxInputs":2,"params":{"temperature":{"type":"number?","description":"default 0"},"topK":{"type":"number?","description":"0 = off"},"topP":{"type":"number?","description":"1 = off"},"seed":{"type":"number?","description":"RNG seed"},"step":{"type":"number?","description":"RNG counter; /api/v3/generate fills it in"},"repetitionPenalty":{"type":"number?","description":"with a history: each distinct id in the window has a positive logit divided by this, a negative one multiplied (1 = off; chat uses 1.1)"},"presencePenalty":{"type":"number?","description":"with a history: subtracted from the logit of each distinct id in the window (0 = off)"},"penaltyWindow":{"type":"number?","description":"how many history rows, ending at penaltyEnd, count (default all)"},"penaltyEnd":{"type":"number?","description":"one past the last history row that counts (default N); a decode graph binds it to pos + 1"}},"features":["sample.penalty"],"addedIn":"v3","core":false},{"op":"scale","summary":"Multiply by a constant.","inputs":["a"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{"factor":{"type":"number","description":"the constant"}},"features":[],"addedIn":"v2","core":true},{"op":"short_conv","summary":"A whole LFM2 gated short-conv block: in_proj, B-gate, conv over the state, C-gate, out_proj. The state is advanced in place.","inputs":["x [T, C]","in_proj [3C, C]","conv [C, 1, K]","out_proj [C, C]","state [K-1, C]"],"output":"[T, C]","minInputs":5,"maxInputs":5,"params":{},"features":[],"writesInput":4,"addedIn":"v3","core":false},{"op":"sigmoid","summary":"1 / (1 + exp(-x)).","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"silu","summary":"x * sigmoid(x) — SiLU / Swish.","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"slice","summary":"A window along the leading axis or the last one. Accepts a model weight directly.","inputs":["a"],"output":"a with the chosen axis shortened","minInputs":1,"maxInputs":1,"params":{"start":{"type":"number","description":"first index"},"length":{"type":"number","description":"how many"},"axis":{"type":"number?","description":"0 (default) or the last axis; -1 means the last"}},"features":[],"addedIn":"v3","core":false},{"op":"softcap","summary":"cap * tanh(x / cap) — Gemma 2 final-logit softcapping.","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{"cap":{"type":"number","description":"e.g. final_logit_softcapping from config.json"}},"features":[],"addedIn":"v3","core":false},{"op":"softmax","summary":"Softmax over the last dimension, max-subtracted so large logits do not overflow.","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"sub","summary":"Elementwise a - b.","inputs":["a","b — broadcast as for add"],"output":"same shape as the input","minInputs":2,"maxInputs":2,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"swiglu","summary":"silu(gate) * up — the Llama/Qwen/Mistral feed-forward gate.","inputs":["gate","up — same shape"],"output":"same shape as the input","minInputs":2,"maxInputs":2,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"tanh","summary":"tanh(x).","inputs":["x"],"output":"same shape as the input","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v3","core":false},{"op":"transpose","summary":"2-D transpose.","inputs":["a [R, C]"],"output":"[C, R]","minInputs":1,"maxInputs":1,"params":{},"features":[],"addedIn":"v2","core":true},{"op":"zeros","summary":"A tensor of zeros, allocated on the worker — how a session allocates its cache without uploading anything.","inputs":[],"output":"params.shape","minInputs":0,"maxInputs":0,"params":{"shape":{"type":"array","description":"the shape"}},"features":[],"addedIn":"v3","core":false}],"features":{"attention.alibi":"ALiBi linear position biases (alibi, alibiMax or alibiSlopes).","attention.bias":"An additive score bias as a fourth input.","attention.scale":"A score scale other than 1/sqrt(headDim).","attention.softcap":"Score softcapping before the mask.","attention.window":"Sliding-window attention.","layernorm.eps":"A LayerNorm epsilon other than the 1e-5 default.","rmsnorm.groupSize":"RMSNorm over groups of channels (per-head q/k norm).","rmsnorm.weightOffset":"RMSNorm multiplying by gamma + offset (Gemma).","rope.interleaved":"Interleaved (GPT-J) channel pairing.","rope.rotaryDim":"Partial rotary embeddings.","rope.scaling":"Rotary frequency scaling: scaling, invFreq or attentionFactor.","sample.penalty":"A token history as a second input, for repetitionPenalty and presencePenalty."}}