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

Sessions and K/V cache

Use Model::generate unless an application needs direct control over the token loop. The low-level Session API owns independent K/V state while sharing the loaded model and its cache arena.

use libmir::{SamplingLogits, runtime::RuntimeError};

let prepared = model.prepare(&request)?;
let mut session = model.session();
let prefill = session.prefill(
    &prepared.tokens.token_ids,
    SamplingLogits::None,
    &mut |_| {},
)?;
let mut next = prefill.next_token.ok_or_else(|| {
    RuntimeError::Backend("device sampling returned no token".into())
})?;

for _ in 0..32 {
    print!("{}", model.descriptor().tokenizer().decode(&[next])?);
    if model.descriptor().tokenizer().stop_token_ids().contains(&next) {
        break;
    }
    next = session
        .decode(next, SamplingLogits::None)?
        .event
        .token_id
        .ok_or_else(|| RuntimeError::Backend("no token".into()))?;
}

println!("{:#?}", session.cache_stats());
Ok::<(), libmir::Error>(())

SamplingLogits::None requests device sampling when supported. Other variants can expose full or candidate logits for an application-owned sampler.

Cache behavior

The library uses page-backed K/V storage. Full ready blocks can become shared prefix entries, and sessions use copy-on-write when a shared tail must diverge. Session::cache_stats reports:

  • resolved storage dtype and quantization mode;
  • total, free, and used blocks;
  • cached prefix count;
  • prefix probes, hits, misses, and matching token counts.

Dropping the session releases its block table. A multimodal prefill deliberately does not publish reusable prefix-cache entries.