Skip to main content

Module dry

Module dry 

Source
Expand description

The DRY repetition sampler (“Don’t Repeat Yourself”), ported from llama.cpp’s llama_sampler_dry (src/llama-sampler.cpp:3078-3400), which is itself a port of Koboldcpp PR 982 by pi6am.

§What it does that the repetition penalty cannot

penalties looks at SINGLE tokens: a token that occurred in the window is made less likely, once. DRY looks at SEQUENCES. It asks, for every token the model could emit next, “how long a repetition of earlier context would emitting this token continue?”, and penalises by multiplier * base ^ (that length - allowed_length). A model looping on a four-token phrase is not emitting one over-represented token, so the repetition penalty barely moves it while DRY’s exponential grows every time round the loop.

§The three parts, and where each one comes from

  • DryBreakers is get_overlapping_token_sequences (src/llama-sampler.cpp:3095): the sequence breakers a caller gives as STRINGS, tokenised against the loaded vocabulary. A breaker is a point the repetition detector refuses to look past, so "\n" stops one paragraph’s phrasing from penalising the next. It has to be done against the model’s own vocabulary because a breaker string is usually not a whole token: ":" may only ever appear as the tail of "foo:", so the entry is keyed on the token that CONTAINS it and carries whatever tokens must follow.
  • DryParams::penalties is llama_sampler_dry_apply (src/llama-sampler.cpp:3151), including the reverse Z-algorithm that finds, in one linear pass, how long a suffix ending at each position also occurs elsewhere in the window.
  • [crate::sampler_chain::Candidates::dry] subtracts the result.

§Why the parameters are a struct with private fields

Because enabling DRY without tokenising its breakers is a silent wrong answer, not an error: the sampler runs, penalises across newlines it was told to stop at, and nothing says so. So there is no way to build an ENABLED DryParams without handing it a DryBreakers, and the only way to build a non-empty DryBreakers is DryBreakers::from_vocab, which needs a vocabulary. A caller that genuinely wants none writes DryBreakers::none and that is visible in the diff.

Structs§

DryBreakers
Sequence breakers, tokenised against one model’s vocabulary.
DryParams
One request’s DRY configuration.
DryRequest
DRY as a caller SPELLS it: four numbers and a list of strings, with the breakers not yet tokenised.
DryVocabMissing
DRY was asked for and there is no vocabulary to tokenise its sequence breakers against.

Constants§

DEFAULT_SEQUENCE_BREAKERS
llama.cpp’s default sequence breakers (common/common.h:259, dry_sequence_breakers = {"\n", ":", "\"", "*"}).

Traits§

DryVocab
What DRY needs from a loaded model’s vocabulary, and nothing else.