Show more information about LoRAs when loading loras in generate page
This commit is contained in:
1 parent
ef8110cef7
commit
1db6083645
2 files changed
+46
-8
No files matched your search
@@ -152,6 +152,9 @@ class InferenceLoRA:
|
||||
self.name = name or os.path.splitext(os.path.basename(path))[0]
|
||||
self.entries: List[LoRAEntry] = []
|
||||
self.unmatched: List[str] = []
|
||||
self.num_keys = 0 # tensors in the file
|
||||
self.num_skipped_keys = 0 # keys with no recognized lora/diff/lokr suffix
|
||||
self.convert_error: Optional[str] = None
|
||||
self._hooks: List = []
|
||||
|
||||
# ---- loading / key resolution ----
|
||||
@@ -163,18 +166,23 @@ class InferenceLoRA:
|
||||
# self.path stays as given: it is the spec identity the engine keys its
|
||||
# loaded stack on.
|
||||
self.local_path = resolve_lora_file(self.path, status_fn=status_fn)
|
||||
if status_fn:
|
||||
status_fn(f"Loading LoRA {self.name} from {self.local_path}")
|
||||
sd = load_file(self.local_path)
|
||||
self.num_keys = len(sd)
|
||||
convert = getattr(holder, "convert_lora_weights_before_load", None)
|
||||
if callable(convert):
|
||||
try:
|
||||
sd = convert(sd)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
self.convert_error = f"{type(e).__name__}: {e}"
|
||||
roots = self._roots(holder)
|
||||
grouped: Dict[Tuple[int, str], dict] = {}
|
||||
self.num_skipped_keys = 0
|
||||
for key, tensor in sd.items():
|
||||
base, part = self._split(key)
|
||||
if part is None:
|
||||
self.num_skipped_keys += 1
|
||||
continue
|
||||
grouped.setdefault(base, {})[part] = tensor
|
||||
self.entries = []
|
||||
@@ -378,6 +386,35 @@ class InferenceLoRA:
|
||||
m_marker = getattr(self, "_marker", None)
|
||||
return merged
|
||||
|
||||
def report(self, max_unmatched: Optional[int] = None) -> str:
|
||||
"""Multi-line load report: file, key counts, matched/unmatched modules, unmatched names."""
|
||||
n_groups = len(self.entries) + len(self.unmatched)
|
||||
lines = [
|
||||
f"LoRA {self.name}: {self.local_path or self.path}",
|
||||
f" {self.num_keys} keys in file -> {n_groups} modules: {len(self.entries)} matched, {len(self.unmatched)} unmatched"
|
||||
+ (f", {self.num_skipped_keys} keys ignored (unrecognized suffix)" if self.num_skipped_keys else ""),
|
||||
]
|
||||
if self.convert_error:
|
||||
lines.append(f" convert_lora_weights_before_load failed, using raw keys: {self.convert_error}")
|
||||
shown = self.unmatched if max_unmatched is None else self.unmatched[:max_unmatched]
|
||||
for u in shown:
|
||||
lines.append(f" unmatched: {u}")
|
||||
if len(shown) < len(self.unmatched):
|
||||
lines.append(f" ... {len(self.unmatched) - len(shown)} more unmatched")
|
||||
return "\n".join(lines)
|
||||
|
||||
def report_line(self, max_unmatched: int = 5) -> str:
|
||||
"""One-line form of report() for status strips."""
|
||||
n_groups = len(self.entries) + len(self.unmatched)
|
||||
line = f"LoRA {self.name}: {len(self.entries)}/{n_groups} modules matched ({self.num_keys} keys)"
|
||||
if self.unmatched:
|
||||
shown = ", ".join(self.unmatched[:max_unmatched])
|
||||
more = len(self.unmatched) - max_unmatched
|
||||
line += f"; {len(self.unmatched)} unmatched: {shown}" + (f" +{more} more" if more > 0 else "")
|
||||
if self.convert_error:
|
||||
line += f"; convert failed: {self.convert_error}"
|
||||
return line
|
||||
|
||||
def summary(self) -> dict:
|
||||
return {
|
||||
"name": self.name,
|
||||
@@ -404,13 +441,14 @@ class LoRAStack:
|
||||
lora = InferenceLoRA(spec["path"], spec.get("strength", 1.0), spec.get("name")).load(
|
||||
self.holder, status_fn=status_fn
|
||||
)
|
||||
print(f"[AITK] {lora.report()}", flush=True)
|
||||
if status_fn:
|
||||
status_fn(
|
||||
f"LoRA {lora.name}: {len(lora.entries)} modules"
|
||||
+ (f", {len(lora.unmatched)} unmatched" if lora.unmatched else "")
|
||||
)
|
||||
status_fn(lora.report_line())
|
||||
if not lora.entries:
|
||||
raise ValueError(f"LoRA {lora.name} matched no modules of this model (unmatched: {lora.unmatched[:3]})")
|
||||
raise ValueError(
|
||||
f"LoRA {lora.name} matched no modules of this model "
|
||||
f"({lora.num_keys} keys, {len(lora.unmatched)} unmatched; see the engine job log for the list)"
|
||||
)
|
||||
self.loras.append(lora)
|
||||
return self
|
||||
|
||||
|
||||
@@ -823,7 +823,7 @@ function GeneratePageInner() {
|
||||
{/* status strip over the stage */}
|
||||
<div className="absolute top-0 left-0 right-0 z-10 px-3 py-1.5 flex items-center gap-2 text-xs text-gray-300 bg-gradient-to-b from-gray-950/80 to-transparent">
|
||||
{running && <Loader2 className="w-3.5 h-3.5 animate-spin text-blue-400" />}
|
||||
<span className="truncate">
|
||||
<span className="truncate" title={running ? statusLine : undefined}>
|
||||
{running
|
||||
? statusLine
|
||||
: selected
|
||||
|
||||
Reference in new issue
Block a user