libmir-metal 0.3.0

Metal inference backend for libmir
use std::time::Instant;

use runtime::backend::{PrefillOutput, PrefillRequest, SamplingLogits};
use uuid::Uuid;

use crate::native::{error::Result, model::LoadedModel, output, prefill::NativePrefill};

pub(super) fn materialize_prefill(
    loaded: &LoadedModel,
    request: &PrefillRequest,
    native: NativePrefill,
    started: Instant,
) -> Result<PrefillOutput> {
    materialize_prefill_parts(
        loaded,
        &request.model.id,
        request.session_id,
        &request.prompt_tokens,
        request.block_table.blocks().len(),
        request.sampling_logits,
        native,
        started,
    )
}

#[allow(clippy::too_many_arguments)]
pub(super) fn materialize_prefill_parts(
    loaded: &LoadedModel,
    model_id: &str,
    session_id: Uuid,
    prompt_tokens: &[u32],
    blocks: usize,
    sampling_logits: SamplingLogits,
    native: NativePrefill,
    started: Instant,
) -> Result<PrefillOutput> {
    let prefix_cache_tokens = native.prefix_cache_tokens;
    let output = output::materialize(loaded, native.output, sampling_logits)?;
    let cached_tokens = loaded.session_cached_tokens(session_id)?;
    let prefix_cache = if prefix_cache_tokens > 0 {
        format!("device prefix hit for {prefix_cache_tokens} tokens")
    } else {
        "device prefix miss".into()
    };
    let trace = format!(
        "native prefill: {} tokens, {}, {} runtime KV blocks, {} cached tokens, {:.3}ms",
        prompt_tokens.len(),
        prefix_cache,
        blocks,
        cached_tokens,
        started.elapsed().as_secs_f64() * 1000.0
    );
    tracing::debug!(
        model_id,
        session_id = %session_id,
        prompt_tokens = prompt_tokens.len(),
        cached_tokens,
        prefix_cache_tokens,
        "native MLX prefill completed"
    );
    Ok(PrefillOutput {
        accepted_tokens: prompt_tokens.len(),
        next_token: output.next_token,
        trace: Some(trace),
        logits: output.logits,
        candidates: output.candidates,
    })
}