diff --git a/python/sglang/srt/lora/lora_registry.py b/python/sglang/srt/lora/lora_registry.py index d31c5ab93..08b7a2812 100644 --- a/python/sglang/srt/lora/lora_registry.py +++ b/python/sglang/srt/lora/lora_registry.py @@ -17,7 +17,7 @@ import asyncio from collections import OrderedDict from dataclasses import dataclass, field, fields from typing import Dict, List, Optional, Union -from uuid import uuid4 +from uuid import NAMESPACE_URL, uuid4, uuid5 from sglang.srt.utils import ConcurrentCounter from sglang.srt.utils.aio_rwlock import RWLock @@ -42,6 +42,16 @@ class LoRARef: if self.lora_id is None: raise ValueError("lora_id cannot be None") + @staticmethod + def deterministic_id(lora_name: str, lora_path: str) -> str: + """Stable ``lora_id`` for ``--lora-paths`` adapters. + + Each node in a multi-node launch parses ``--lora-paths`` independently; + ``uuid4`` would mint a different id per node for the same adapter, + breaking cross-node lookups when the master broadcasts a request id. + """ + return uuid5(NAMESPACE_URL, f"{lora_name}\0{lora_path}").hex + def __str__(self) -> str: parts = [ f"{f.name}={value}" diff --git a/python/sglang/srt/server_args.py b/python/sglang/srt/server_args.py index 30a3612d9..d65ae6f9b 100644 --- a/python/sglang/srt/server_args.py +++ b/python/sglang/srt/server_args.py @@ -7011,17 +7011,26 @@ class ServerArgs: if "=" in lora_path: name, path = lora_path.split("=", 1) lora_ref = LoRARef( - lora_name=name, lora_path=path, pinned=False + lora_id=LoRARef.deterministic_id(name, path), + lora_name=name, + lora_path=path, + pinned=False, ) else: lora_ref = LoRARef( - lora_name=lora_path, lora_path=lora_path, pinned=False + lora_id=LoRARef.deterministic_id(lora_path, lora_path), + lora_name=lora_path, + lora_path=lora_path, + pinned=False, ) elif isinstance(lora_path, dict): assert ( "lora_name" in lora_path and "lora_path" in lora_path ), f"When providing LoRA paths as a list of dict, each dict should contain 'lora_name' and 'lora_path' keys. Got: {lora_path}" lora_ref = LoRARef( + lora_id=LoRARef.deterministic_id( + lora_path["lora_name"], lora_path["lora_path"] + ), lora_name=lora_path["lora_name"], lora_path=lora_path["lora_path"], pinned=lora_path.get("pinned", False), @@ -7034,7 +7043,12 @@ class ServerArgs: self.lora_paths.append(lora_ref) elif isinstance(self.lora_paths, dict): self.lora_paths = [ - LoRARef(lora_name=k, lora_path=v, pinned=False) + LoRARef( + lora_id=LoRARef.deterministic_id(k, v), + lora_name=k, + lora_path=v, + pinned=False, + ) for k, v in self.lora_paths.items() ] elif self.lora_paths is None: