use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InferenceConfig {
pub model_id: String,
pub filename: String,
pub prompt: String,
pub max_tokens: usize,
pub temperature: f64,
pub max_duration_secs: Option<u64>,
#[serde(default = "default_stop_on_eos")]
pub stop_on_eos: bool,
}
fn default_stop_on_eos() -> bool {
true
}
impl Default for InferenceConfig {
fn default() -> Self {
Self {
model_id: "bartowski/SmolLM2-360M-Instruct-GGUF".to_string(),
filename: "SmolLM2-360M-Instruct-Q4_K_M.gguf".to_string(),
prompt: "Tell me a story about a helpful robot.".to_string(),
max_tokens: 100,
temperature: 0.7,
max_duration_secs: Some(10),
stop_on_eos: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InferenceResult {
pub tokens_per_second: f64,
pub total_tokens: usize,
pub duration_ms: u64,
pub generated_text: String,
pub device_used: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum StopReason {
MaxTokens,
EosToken,
TimeLimit,
NoTokensRequested,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InferenceTelemetry {
pub prompt_tokens: usize,
pub generated_tokens: usize,
pub tokenization_ms: f64,
pub prompt_tensor_ms: f64,
pub prefill_ms: f64,
pub prefill_tokens_per_second: f64,
pub time_to_first_token_ms: f64,
pub decode_ms: f64,
pub decode_tokens_per_second: f64,
pub avg_inter_token_ms: f64,
pub p50_inter_token_ms: f64,
pub p95_inter_token_ms: f64,
pub sampling_ms: f64,
pub detokenize_ms: f64,
pub callback_ms: f64,
pub stop_reason: StopReason,
pub device_used: String,
pub device_type: String,
pub architecture: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProfiledInferenceResult {
pub result: InferenceResult,
pub telemetry: InferenceTelemetry,
}