abyo_speculate/methods/mod.rs
1//! SD method implementations.
2//!
3//! Each method exposes the same `Decoder` trait so the [`crate::SpeculateEngine`]
4//! can dispatch generically.
5
6pub mod eagle;
7pub mod eagle3;
8pub mod medusa;
9pub mod vanilla;
10
11/// Identifier for which Speculative Decoding algorithm to use.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
13#[serde(rename_all = "kebab-case")]
14pub enum Method {
15 /// Plain autoregressive — no speculation, useful as a baseline.
16 Autoregressive,
17 /// Leviathan et al. 2023 — separate draft model + rejection sampling.
18 Vanilla,
19 /// Cai et al. 2024 — multiple decoding heads, no separate draft model.
20 Medusa,
21 /// Li et al. 2024 — feature-level draft + dynamic tree.
22 Eagle2,
23 /// Li et al. 2025 — multi-layer feature draft.
24 Eagle3,
25}
26
27impl Method {
28 /// Human-readable name (matches the published paper convention).
29 pub const fn name(self) -> &'static str {
30 match self {
31 Method::Autoregressive => "autoregressive",
32 Method::Vanilla => "vanilla-sd",
33 Method::Medusa => "medusa",
34 Method::Eagle2 => "eagle-2",
35 Method::Eagle3 => "eagle-3",
36 }
37 }
38
39 /// Whether this method requires a separate draft / heads asset
40 /// loaded alongside the target. Medusa counts even though its heads
41 /// aren't a "draft model" in the Leviathan sense — they're still a
42 /// separate artifact that must be attached.
43 pub const fn needs_draft_model(self) -> bool {
44 matches!(
45 self,
46 Method::Vanilla | Method::Medusa | Method::Eagle2 | Method::Eagle3
47 )
48 }
49}