Unverified Commit 684107c4 authored by Biswa Panda's avatar Biswa Panda Committed by GitHub
Browse files

feat: generate deterministic lora id from lora name (#4457)

parent 04486c1d
...@@ -138,6 +138,7 @@ fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> { ...@@ -138,6 +138,7 @@ fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> {
} }
m.add_function(wrap_pyfunction!(llm::kv::compute_block_hash_for_seq_py, m)?)?; m.add_function(wrap_pyfunction!(llm::kv::compute_block_hash_for_seq_py, m)?)?;
m.add_function(wrap_pyfunction!(lora_name_to_id, m)?)?;
m.add_function(wrap_pyfunction!(log_message, m)?)?; m.add_function(wrap_pyfunction!(log_message, m)?)?;
m.add_function(wrap_pyfunction!(register_llm, m)?)?; m.add_function(wrap_pyfunction!(register_llm, m)?)?;
m.add_function(wrap_pyfunction!(fetch_llm, m)?)?; m.add_function(wrap_pyfunction!(fetch_llm, m)?)?;
...@@ -215,6 +216,13 @@ fn log_message(level: &str, message: &str, module: &str, file: &str, line: u32) ...@@ -215,6 +216,13 @@ fn log_message(level: &str, message: &str, module: &str, file: &str, line: u32)
logging::log_message(level, message, module, file, line); logging::log_message(level, message, module, file, line);
} }
/// Generate a deterministic signed int32 ID from a LoRA name using blake3 hash.
#[pyfunction]
#[pyo3(text_signature = "(lora_name)")]
fn lora_name_to_id(lora_name: &str) -> i32 {
llm_rs::utils::lora_name_to_id(lora_name)
}
/// Create an engine and attach it to an endpoint to make it visible to the frontend. /// Create an engine and attach it to an endpoint to make it visible to the frontend.
/// This is the main way you create a Dynamo worker / backend. /// This is the main way you create a Dynamo worker / backend.
#[pyfunction] #[pyfunction]
......
...@@ -36,6 +36,7 @@ from dynamo._core import ZmqKvEventPublisher as ZmqKvEventPublisher ...@@ -36,6 +36,7 @@ from dynamo._core import ZmqKvEventPublisher as ZmqKvEventPublisher
from dynamo._core import ZmqKvEventPublisherConfig as ZmqKvEventPublisherConfig from dynamo._core import ZmqKvEventPublisherConfig as ZmqKvEventPublisherConfig
from dynamo._core import compute_block_hash_for_seq_py as compute_block_hash_for_seq_py from dynamo._core import compute_block_hash_for_seq_py as compute_block_hash_for_seq_py
from dynamo._core import fetch_llm as fetch_llm from dynamo._core import fetch_llm as fetch_llm
from dynamo._core import lora_name_to_id as lora_name_to_id
from dynamo._core import make_engine from dynamo._core import make_engine
from dynamo._core import register_llm as register_llm from dynamo._core import register_llm as register_llm
from dynamo._core import run_input from dynamo._core import run_input
......
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
from dynamo.llm import lora_name_to_id
max_int32 = 0x7FFFFFFF
class TestLoraNameToId:
def test_import_function(self):
assert callable(lora_name_to_id)
def test_returns_positive_integer_for_different_names(self):
for i in range(100):
result = lora_name_to_id(f"test_lora_{i}")
assert isinstance(result, int)
assert 1 <= result <= max_int32
def test_different_names_produce_different_ids(self):
id1 = lora_name_to_id("lora_adapter_1")
id2 = lora_name_to_id("lora_adapter_2")
assert id1 != id2
def test_consistency_across_multiple_calls(self):
test_names = [f"lora_{i}" for i in range(100)]
results_first = [lora_name_to_id(name) for name in test_names]
results_second = [lora_name_to_id(name) for name in test_names]
assert results_first == results_second
// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use blake3;
/// Generate a deterministic signed int32 ID from a LoRA name using blake3 hash.
pub fn lora_name_to_id(lora_name: &str) -> i32 {
let hash = blake3::hash(lora_name.as_bytes());
let hash_bytes = hash.as_bytes();
let mut bytes_array = [0u8; 8];
bytes_array.copy_from_slice(&hash_bytes[..8]);
let hash_u64 = u64::from_be_bytes(bytes_array);
let lora_id: i32 = ((hash_u64 & 0x7FFFFFFF) as i32).abs();
// Ensure non-zero ID
if lora_id == 0 { 1 } else { lora_id }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lora_name_to_id() {
let id = lora_name_to_id("test_lora");
assert!(1 <= id);
let id1 = lora_name_to_id("test_lora");
let id2 = lora_name_to_id("test_lora");
assert_eq!(id1, id2);
}
#[test]
fn test_lora_id_stability_across_version() {
let id1 = lora_name_to_id("test_lora");
assert_eq!(id1, 1983627077);
}
}
// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
pub mod lora;
pub mod prefix_matcher; pub mod prefix_matcher;
pub use lora::lora_name_to_id;
pub use prefix_matcher::{MarkerMatcher, MatchResult}; pub use prefix_matcher::{MarkerMatcher, MatchResult};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment