dynamo-llm 1.3.0

Dynamo LLM Library
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! LoRA Filter
//!
//! Pre-filters the set of eligible workers for a LoRA request based on the routing
//! table and loaded state.

use std::collections::{HashMap, HashSet};

use crate::kv_router::protocols::WorkerWithDpRank;
use crate::local_model::runtime_config::ModelRuntimeConfig;
use crate::lora::routing::RendezvousHasher;
use crate::lora::routing::table::LoraRoutingTable;
use crate::lora::state_tracker::LoraStateTracker;

type WorkerId = u64;

/// Filters workers for LoRA-aware routing.
#[derive(Clone)]
pub struct LoraFilter {
    routing_table: LoraRoutingTable,
    state_tracker: LoraStateTracker,
}

impl LoraFilter {
    pub fn new(routing_table: LoraRoutingTable, state_tracker: LoraStateTracker) -> Self {
        Self {
            routing_table,
            state_tracker,
        }
    }

    /// Bounded fallback for an existing routing-table entry whose own replica workers are all
    /// unavailable (worker removal / controller lag). Instead of widening to EVERY available worker
    /// — which scatters adapter traffic across the cluster and forces cold loads on workers the
    /// controller never picked, bypassing its placement/capacity decisions — narrow to:
    ///   1. workers that already have this adapter loaded (no new load), else
    ///   2. a single deterministic HRW-pinned available worker (a bounded cold load that every
    ///      router instance agrees on, coordination-free), else
    ///   3. nothing (only when `available` is empty).
    ///
    /// The HRW pin ranks by worker id (dp_rank collapsed to 0, since the filter operates on worker
    /// ids): it need not match the controller's exact pin — that worker is unavailable here — only
    /// be deterministic given the same available set.
    fn bounded_fallback(&self, lora_name: &str, available: &[u64]) -> Vec<u64> {
        let loaded = self.state_tracker.get_loaded_workers(lora_name);
        if !loaded.is_empty() {
            let loaded_ids: HashSet<u64> = loaded.iter().map(|w| w.worker_id).collect();
            let live_loaded: Vec<u64> = available
                .iter()
                .copied()
                .filter(|id| loaded_ids.contains(id))
                .collect();
            if !live_loaded.is_empty() {
                tracing::debug!(
                    lora = lora_name,
                    count = live_loaded.len(),
                    "Replica workers unavailable; narrowed to known-loaded live workers"
                );
                return live_loaded;
            }
        }
        // Deterministic single HRW pin among available workers (highest score, ties broken by id).
        if let Some(pin) = available.iter().copied().max_by(|&a, &b| {
            let sa = RendezvousHasher::compute_score(lora_name, WorkerWithDpRank::new(a, 0));
            let sb = RendezvousHasher::compute_score(lora_name, WorkerWithDpRank::new(b, 0));
            sa.cmp(&sb).then(a.cmp(&b))
        }) {
            tracing::debug!(
                lora = lora_name,
                worker_id = pin,
                "Replica workers unavailable and adapter not loaded; bounded HRW pin (no scatter)"
            );
            return vec![pin];
        }
        Vec::new()
    }

    /// Filter available worker IDs for a LoRA request.
    ///
    /// Logic:
    /// - `lora_name` is None: return all workers (base model request)
    /// - Active entry: prefer loaded workers in replica set, fall back to full replica set
    /// - Inactive entry: return single HRW-pinned worker (cold-start determinism)
    /// - Not in routing table: prefer known-loaded workers, fall back to all workers
    pub fn filter_worker_ids_for_lora(
        &self,
        lora_name: Option<&str>,
        available: &[u64],
    ) -> Vec<u64> {
        let Some(lora_name) = lora_name else {
            return available.to_vec();
        };

        let Some(config) = self.routing_table.get_config(lora_name) else {
            // No routing-table entry yet (controller disabled, or before the first tick).
            // Prefer workers that actually have this adapter loaded (from the state tracker)
            // so we don't scatter to every worker; fall back to all available only when none
            // are known-loaded. This makes the "loaded-worker fallback" real even when dynamic
            // allocation (the controller) is disabled.
            let loaded = self.state_tracker.get_loaded_workers(lora_name);
            if !loaded.is_empty() {
                // O(1) membership instead of scanning `loaded` per available worker
                // (this fallback runs on every LoRA request when allocation is disabled).
                let loaded_ids_set: HashSet<u64> = loaded.iter().map(|w| w.worker_id).collect();
                let loaded_ids: Vec<u64> = available
                    .iter()
                    .copied()
                    .filter(|id| loaded_ids_set.contains(id))
                    .collect();
                if !loaded_ids.is_empty() {
                    tracing::debug!(
                        lora = lora_name,
                        count = loaded_ids.len(),
                        "LoRA not in routing table; narrowed to known-loaded workers"
                    );
                    return loaded_ids;
                }
            }
            tracing::debug!(
                lora = lora_name,
                "LoRA not in routing table and not known-loaded, returning all workers"
            );
            return available.to_vec();
        };

        let replica_id_set: HashSet<u64> = config.replica_set.iter().map(|w| w.worker_id).collect();

        if config.is_active {
            let loaded = self.state_tracker.get_loaded_workers(lora_name);
            let loaded_ids: HashSet<u64> = loaded.iter().map(|w| w.worker_id).collect();

            // Prefer: replica set ∩ loaded ∩ available
            let loaded_in_set: Vec<u64> = available
                .iter()
                .copied()
                .filter(|id| replica_id_set.contains(id) && loaded_ids.contains(id))
                .collect();
            if !loaded_in_set.is_empty() {
                tracing::debug!(
                    lora = lora_name,
                    count = loaded_in_set.len(),
                    "Filtered to loaded workers in replica set"
                );
                return loaded_in_set;
            }

            // Fall back: replica set ∩ available (lazy load)
            let replica_set: Vec<u64> = available
                .iter()
                .copied()
                .filter(|id| replica_id_set.contains(id))
                .collect();
            if !replica_set.is_empty() {
                tracing::debug!(
                    lora = lora_name,
                    count = replica_set.len(),
                    "LoRA not loaded yet, returning full replica set for lazy load"
                );
                return replica_set;
            }

            tracing::warn!(
                lora = lora_name,
                "Replica set workers all unavailable; using bounded fallback (no scatter)"
            );
            self.bounded_fallback(lora_name, available)
        } else {
            // Inactive: cold-start pin
            if let Some(pin_id) = config.replica_set.first().map(|w| w.worker_id)
                && available.contains(&pin_id)
            {
                tracing::debug!(
                    lora = lora_name,
                    worker_id = pin_id,
                    "Cold-start: routing to HRW-pinned worker"
                );
                return vec![pin_id];
            }
            tracing::warn!(
                lora = lora_name,
                "Cold-start pin worker unavailable; using bounded fallback (no scatter)"
            );
            self.bounded_fallback(lora_name, available)
        }
    }

    /// Filter workers for a LoRA request (HashMap variant for KV routing).
    pub fn filter_workers_for_lora(
        &self,
        lora_name: Option<&str>,
        workers: &HashMap<WorkerId, ModelRuntimeConfig>,
    ) -> HashMap<WorkerId, ModelRuntimeConfig> {
        let available_ids: Vec<u64> = workers.keys().copied().collect();
        let selected_ids = self.filter_worker_ids_for_lora(lora_name, &available_ids);

        if selected_ids.len() == available_ids.len() {
            return workers.clone();
        }

        let selected_set: HashSet<u64> = selected_ids.into_iter().collect();
        workers
            .iter()
            .filter(|(wid, _)| selected_set.contains(wid))
            .map(|(k, v)| (*k, v.clone()))
            .collect()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::kv_router::protocols::WorkerWithDpRank;
    use crate::lora::routing::table::{LoraReplicaConfig, LoraRoutingTable};
    use crate::lora::state_tracker::LoraStateTracker;
    use crate::model_card::LoraInfo;
    use std::time::Instant;

    fn make_workers_map(ids: &[u64]) -> HashMap<WorkerId, ModelRuntimeConfig> {
        ids.iter()
            .map(|&id| (id, ModelRuntimeConfig::default()))
            .collect()
    }

    fn make_worker(id: u64) -> WorkerWithDpRank {
        WorkerWithDpRank::new(id, 0)
    }

    fn make_lora_info(name: &str) -> LoraInfo {
        LoraInfo {
            name: name.to_string(),
            max_gpu_lora_count: Some(4),
        }
    }

    #[test]
    fn test_no_lora_returns_all_workers() {
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();
        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(None, &workers);
        assert_eq!(result.len(), 3);
    }

    #[test]
    fn test_not_in_routing_table_returns_all() {
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();
        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("unknown-lora"), &workers);
        assert_eq!(result.len(), 3);
    }

    #[test]
    fn test_not_in_routing_table_narrows_to_loaded_workers() {
        // No routing-table entry (controller disabled / pre-first-tick), but the state
        // tracker knows the adapter is loaded on a subset of workers. The fallback must
        // narrow to those known-loaded workers rather than scattering to all available.
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();
        st.handle_mdc_addition(make_worker(2), &make_lora_info("lora-a"));

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-a"), &workers);
        assert_eq!(result.len(), 1);
        assert!(result.contains_key(&2));
    }

    #[test]
    fn test_not_in_routing_table_loaded_worker_unavailable_falls_back_to_all() {
        // The adapter is known-loaded, but on a worker that is not in the available set.
        // With no usable loaded worker, the fallback returns all available workers so the
        // request stays routable.
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();
        st.handle_mdc_addition(make_worker(9), &make_lora_info("lora-a"));

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-a"), &workers);
        assert_eq!(result.len(), 3);
    }

    #[test]
    fn test_active_lora_filters_to_loaded_workers() {
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();

        rt.update_allocation(
            "lora-a".to_string(),
            LoraReplicaConfig {
                lora_name: "lora-a".to_string(),
                replica_factor: 2,
                replica_set: vec![make_worker(1), make_worker(2)],
                updated_at: Instant::now(),
                is_active: true,
            },
        );
        st.handle_mdc_addition(make_worker(1), &make_lora_info("lora-a"));

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-a"), &workers);
        assert_eq!(result.len(), 1);
        assert!(result.contains_key(&1));
    }

    #[test]
    fn test_active_lora_falls_back_to_replica_set() {
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();

        rt.update_allocation(
            "lora-a".to_string(),
            LoraReplicaConfig {
                lora_name: "lora-a".to_string(),
                replica_factor: 2,
                replica_set: vec![make_worker(1), make_worker(2)],
                updated_at: Instant::now(),
                is_active: true,
            },
        );

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-a"), &workers);
        assert_eq!(result.len(), 2);
        assert!(result.contains_key(&1));
        assert!(result.contains_key(&2));
    }

    #[test]
    fn test_inactive_lora_cold_start_pin() {
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();

        rt.update_allocation(
            "lora-b".to_string(),
            LoraReplicaConfig {
                lora_name: "lora-b".to_string(),
                replica_factor: 1,
                replica_set: vec![make_worker(2)],
                updated_at: Instant::now(),
                is_active: false,
            },
        );

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-b"), &workers);
        assert_eq!(result.len(), 1);
        assert!(result.contains_key(&2));
    }

    #[test]
    fn test_inactive_pin_worker_unavailable_uses_bounded_pin() {
        // Inactive cold-start pin worker is gone and the adapter is loaded nowhere: the fallback
        // must bound to a SINGLE deterministic HRW-pinned available worker, not scatter to all.
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();

        rt.update_allocation(
            "lora-b".to_string(),
            LoraReplicaConfig {
                lora_name: "lora-b".to_string(),
                replica_factor: 1,
                replica_set: vec![make_worker(5)],
                updated_at: Instant::now(),
                is_active: false,
            },
        );

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-b"), &workers);
        assert_eq!(
            result.len(),
            1,
            "must bound to one worker, not scatter to all three"
        );
        // Deterministic: the same inputs always resolve to the same single pin.
        let again = filter.filter_workers_for_lora(Some("lora-b"), &workers);
        assert_eq!(
            result.keys().collect::<Vec<_>>(),
            again.keys().collect::<Vec<_>>(),
            "bounded HRW pin must be deterministic"
        );
    }

    #[test]
    fn test_active_all_replicas_unavailable_prefers_known_loaded() {
        // Active entry whose entire replica set is unavailable, but the adapter is still loaded on
        // a live worker OUTSIDE the replica set: route there (no new load), never scatter.
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();
        rt.update_allocation(
            "lora-a".to_string(),
            LoraReplicaConfig {
                lora_name: "lora-a".to_string(),
                replica_factor: 2,
                replica_set: vec![make_worker(8), make_worker(9)], // both gone
                updated_at: Instant::now(),
                is_active: true,
            },
        );
        // Adapter is actually loaded on live worker 2 (not in the replica set).
        st.handle_mdc_addition(make_worker(2), &make_lora_info("lora-a"));

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-a"), &workers);
        assert_eq!(
            result.len(),
            1,
            "must narrow to the known-loaded worker, not scatter"
        );
        assert!(result.contains_key(&2));
    }

    #[test]
    fn test_active_all_replicas_unavailable_not_loaded_uses_bounded_pin() {
        // Active entry, entire replica set unavailable, adapter loaded nowhere: bound to a single
        // deterministic HRW pin rather than scattering cold loads across every worker.
        let rt = LoraRoutingTable::new();
        let st = LoraStateTracker::new();
        rt.update_allocation(
            "lora-a".to_string(),
            LoraReplicaConfig {
                lora_name: "lora-a".to_string(),
                replica_factor: 2,
                replica_set: vec![make_worker(8), make_worker(9)],
                updated_at: Instant::now(),
                is_active: true,
            },
        );

        let filter = LoraFilter::new(rt, st);
        let workers = make_workers_map(&[1, 2, 3]);

        let result = filter.filter_workers_for_lora(Some("lora-a"), &workers);
        assert_eq!(
            result.len(),
            1,
            "must bound to one worker, not scatter to all three"
        );
    }
}