Skip to main content

Module encoder

Module encoder 

Source
Expand description

The seam for encoder-only (embedding) models, which is deliberately not crate::engine::Engine.

§Why a second trait and not a variant of the first

crate::engine::Engine is forward_token(token_id, pos, &mut State) -> Vec<f32>: one token in, one logit vector out, carrying per-layer state forward. Every part of that signature is an autoregression assumption, and a BERT encoder violates all of them:

  • There is no state to carry. Attention is bidirectional, so token 0’s output depends on token 7. Nothing can be computed until the whole sequence is present, and nothing computed for one sequence is reusable for the next. A KV cache is not merely unnecessary here, it is meaningless — there is no “next token” for a cached key to be attended to by.
  • There are no logits. The result is n_tokens × n_embd hidden states (llama.cpp’s res->t_embd); this checkpoint has no output head at all, and token_embd.weight is not tied to one.
  • pos is not a cursor, it is an index into a learned table. BERT adds position_embd.weight[i] to the token embedding rather than rotating Q/K, which is why the sequence length is hard-capped by n_ctx_train instead of merely degrading past it.

Forcing that through Engine would mean a State that is a pretend-cache, a forward_token that can only be called with the last position after a hidden batch call, and a vocab_size that has no meaning. The Kimi comment on Engine already records the cost of bending a trait around a model it does not fit; this is the same judgement, made before rather than after.

So: TextEncoder is sequence-in, matrix-out, stateless. What the two seams do share is pooling (crate::pooling), which is why that lives in its own module and not in either of them.

Structs§

PairSequence
One two-segment encoder input: the token ids and, for each of them, which half of the pair it belongs to.

Enums§

EncodeError

Traits§

TextEncoder
A model that turns a whole token sequence into hidden states in one pass, with no carried state and no logits.