ferrum_interfaces/engine.rs
1//! Inference engine interfaces — split per modality.
2//!
3//! Phase 5a step 2 splits the historical mega-trait (which mixed LLM
4//! generation, embedding, transcription, and TTS in one) into a base
5//! lifecycle trait and four modality-specific supertraits. Each
6//! engine impl now implements exactly the trait its modality needs;
7//! no more inert "unsupported" stubs.
8
9use async_trait::async_trait;
10use ferrum_types::{
11 EngineConfig, ExecutorAdmissionSnapshot, InferenceRequest, InferenceResponse, Result,
12 StreamChunk,
13};
14use futures::Stream;
15use std::pin::Pin;
16
17/// Lifecycle / status methods shared by every engine kind.
18///
19/// LLM engines, embedders, transcribers, and TTS services all expose
20/// the same minimal status/metrics surface to the server / CLI. The
21/// modality-specific traits below extend this base.
22#[async_trait]
23pub trait InferenceEngine: Send + Sync {
24 /// Get current engine status.
25 async fn status(&self) -> ferrum_types::EngineStatus;
26
27 /// Shutdown engine gracefully.
28 async fn shutdown(&self) -> Result<()>;
29
30 /// Get engine configuration.
31 fn config(&self) -> &EngineConfig;
32
33 /// Get engine metrics.
34 fn metrics(&self) -> ferrum_types::EngineMetrics;
35
36 /// Health check.
37 async fn health_check(&self) -> ferrum_types::HealthStatus;
38
39 /// Optional cache metrics emitted by concrete LLM engines.
40 ///
41 /// The default keeps non-LLM and stub engines source-compatible. Real
42 /// engines can expose prefix/session cache counters without forcing those
43 /// fields into every modality's core metrics type.
44 fn cache_metrics_snapshot(&self) -> Option<serde_json::Value> {
45 None
46 }
47
48 /// Optional compact provider-attribution witness from the active model
49 /// executor. The default keeps non-vNext engines source-compatible.
50 fn execution_attribution_snapshot(&self) -> Option<serde_json::Value> {
51 None
52 }
53
54 /// Runtime-authoritative admission state. Startup sizing estimates are
55 /// intentionally not accepted through this method.
56 fn admission_snapshot(&self) -> Result<Option<ExecutorAdmissionSnapshot>> {
57 Ok(None)
58 }
59
60 /// Optional LoRA runtime metrics emitted by concrete LLM engines.
61 fn lora_metrics_snapshot(&self) -> Option<serde_json::Value> {
62 None
63 }
64}
65
66/// LLM text-generation engine.
67///
68/// Implemented by `ContinuousBatchEngine` (the production path) and
69/// `DefaultInferenceEngine` (legacy reference path). Backs
70/// `/v1/chat/completions` and `/v1/completions`.
71#[async_trait]
72pub trait LlmInferenceEngine: InferenceEngine {
73 /// Effective per-request capacity in tokens, including input and output.
74 /// Implementations must report the limit used by request admission, not
75 /// the model weights' nominal context window. None means unreported.
76 fn context_capacity(&self) -> Option<usize> {
77 None
78 }
79
80 /// Execute single inference request.
81 async fn infer(&self, request: InferenceRequest) -> Result<InferenceResponse>;
82
83 /// Execute streaming inference request.
84 async fn infer_stream(
85 &self,
86 request: InferenceRequest,
87 ) -> Result<Pin<Box<dyn Stream<Item = Result<StreamChunk>> + Send>>>;
88}
89
90/// Embedding engine (CLIP, BERT, etc.).
91///
92/// Backs `/v1/embeddings`. Distinct from LLM engines — no token
93/// generation, no scheduling, no KV cache.
94#[async_trait]
95pub trait EmbedEngine: InferenceEngine {
96 /// Embed raw text string → float vector (engine handles tokenization).
97 async fn embed_text(&self, text: &str) -> Result<Vec<f32>>;
98
99 /// Embed image (file path or base64) → float vector.
100 async fn embed_image(&self, image: &str) -> Result<Vec<f32>>;
101
102 /// Get embedding dimension.
103 fn embedding_dim(&self) -> usize;
104}
105
106/// Speech-to-text (Whisper) engine.
107///
108/// Backs `/v1/audio/transcriptions`.
109#[async_trait]
110pub trait TranscribeEngine: InferenceEngine {
111 /// Transcribe audio file → text.
112 async fn transcribe_file(&self, path: &str, language: Option<&str>) -> Result<String>;
113
114 /// Transcribe audio bytes (WAV / etc.) → text.
115 async fn transcribe_bytes(&self, data: &[u8], language: Option<&str>) -> Result<String>;
116}
117
118/// Text-to-speech (Qwen3-TTS, etc.) engine.
119///
120/// Backs `/v1/audio/speech`.
121#[async_trait]
122pub trait TtsEngine: InferenceEngine {
123 /// Synthesize speech → PCM audio chunks (streaming).
124 /// Returns Vec of PCM f32 samples per chunk.
125 async fn synthesize_speech(
126 &self,
127 text: &str,
128 language: Option<&str>,
129 chunk_frames: usize,
130 ) -> Result<Vec<Vec<f32>>>;
131
132 /// Get TTS sample rate.
133 fn tts_sample_rate(&self) -> u32;
134}
135
136/// Advanced engine capabilities — opt-in addition to LLM engines that
137/// support batching / speculation / runtime reconfig / diagnostics.
138#[async_trait]
139pub trait AdvancedInferenceEngine: LlmInferenceEngine {
140 /// Execute batch inference.
141 async fn infer_batch(
142 &self,
143 requests: Vec<InferenceRequest>,
144 ) -> Result<Vec<Result<InferenceResponse>>>;
145
146 /// Execute speculative inference.
147 async fn infer_speculative(
148 &self,
149 request: InferenceRequest,
150 speculation_config: ferrum_types::SpeculationConfig,
151 ) -> Result<InferenceResponse>;
152
153 /// Warm up engine with sample requests.
154 async fn warmup(
155 &mut self,
156 warmup_requests: Vec<InferenceRequest>,
157 ) -> Result<ferrum_types::WarmupResult>;
158
159 /// Configure engine at runtime.
160 async fn reconfigure(&mut self, config: EngineConfig) -> Result<()>;
161
162 /// Get detailed diagnostics.
163 async fn diagnostics(&self) -> ferrum_types::DiagnosticsReport;
164
165 /// Export engine state for debugging.
166 async fn export_state(&self) -> Result<ferrum_types::EngineState>;
167
168 /// Import engine state for debugging/testing.
169 async fn import_state(&mut self, state: ferrum_types::EngineState) -> Result<()>;
170}
171
172/// Speculation configuration for speculative decoding.
173pub type SpeculationConfig = ferrum_types::SpeculationConfig;
174
175/// Hardware constraints alias.
176pub type HardwareConstraints = ferrum_types::HardwareConstraints;
177
178/// Request characteristics alias.
179pub type RequestCharacteristics = ferrum_types::RequestCharacteristics;
180
181/// Latency requirements alias.
182pub type LatencyRequirements = ferrum_types::LatencyRequirements;