[LoRA] Use deterministic lora_id for --lora-paths so multi-node ranks agree (#24555)
Co-authored-by: gh1595 <278903827+gh1595@users.noreply.github.com>
This commit is contained in:
@@ -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}"
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user