-
-
Notifications
You must be signed in to change notification settings - Fork 35
fix(worker,models): audit hotfixes - manifest crash, VRAM fail-open, real min_ram_mb key #1767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,16 +87,32 @@ async def reserve( | |
| ) | ||
|
|
||
| async with self._lock: | ||
| free_mb, total_mb = self._probe_vram() | ||
| effective_free = max(0, free_mb - self._reserved_vram_mb) | ||
|
|
||
| if effective_free < vram_mb: | ||
| logger.debug( | ||
| "vram-reservation: denied — need %d MiB, have %d MiB " | ||
| "(%d free − %d reserved)", | ||
| vram_mb, effective_free, free_mb, self._reserved_vram_mb, | ||
| # Probe in a thread: nvidia-smi is a blocking subprocess and this | ||
| # runs on a request hot path while holding the lock. | ||
| probe = await asyncio.to_thread(self._probe_vram) | ||
| if probe is None: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [WARNING]: Fail-open conflates "no nvidia-smi" with "probe errored", over-admitting on real NVIDIA hardware
Consider letting Reply with |
||
| # No VRAM probe on this hardware (AMD/Apple/Rockchip or a | ||
| # failed nvidia-smi). Fail OPEN, matching the cluster lease | ||
| # ledger's convention (manager.claim_lease): we cannot prove | ||
| # insufficiency, so admit and keep bookkeeping only. A closed | ||
| # fail here would 503 every model pull on non-NVIDIA hosts. | ||
| free_mb, total_mb = 0, 0 | ||
| effective_free = vram_mb # unknown; grant-log then shows 0 | ||
| logger.info( | ||
| "vram-reservation: no VRAM probe available; admitting %d " | ||
| "MiB for %r unenforced (bookkeeping only)", vram_mb, caller, | ||
| ) | ||
| return None | ||
| else: | ||
| free_mb, total_mb = probe | ||
| effective_free = max(0, free_mb - self._reserved_vram_mb) | ||
|
|
||
| if effective_free < vram_mb: | ||
| logger.debug( | ||
| "vram-reservation: denied — need %d MiB, have %d MiB " | ||
| "(%d free − %d reserved)", | ||
| vram_mb, effective_free, free_mb, self._reserved_vram_mb, | ||
| ) | ||
| return None | ||
|
|
||
| reservation_id = f"vr_{secrets.token_hex(4)}" | ||
| reservation = VramReservation( | ||
|
|
@@ -148,15 +164,25 @@ def pending_count(self) -> int: | |
|
|
||
| def available_vram(self) -> tuple[int, int]: | ||
| """Return ``(effective_free_mb, total_mb)`` after subtracting | ||
| in-flight reservations from the hardware probe.""" | ||
| free_mb, total_mb = self._probe_vram() | ||
| in-flight reservations from the hardware probe. | ||
|
|
||
| When no probe is available, returns ``(0, 0)``; callers on that | ||
| path should already have been admitted fail-open by :meth:`reserve` | ||
| (a deny message never reports these zeros as real capacity). | ||
| """ | ||
| probe = self._probe_vram() | ||
| if probe is None: | ||
| return 0, 0 | ||
| free_mb, total_mb = probe | ||
| effective_free = max(0, free_mb - self._reserved_vram_mb) | ||
| return effective_free, total_mb | ||
|
|
||
| def stats(self) -> dict: | ||
| """Return a snapshot for monitoring / debug endpoints.""" | ||
| free_mb, total_mb = self._probe_vram() | ||
| probe = self._probe_vram() | ||
| free_mb, total_mb = probe if probe is not None else (0, 0) | ||
| return { | ||
| "probe_available": probe is not None, | ||
| "free_vram_mb": free_mb, | ||
| "total_vram_mb": total_mb, | ||
| "reserved_vram_mb": self._reserved_vram_mb, | ||
|
|
@@ -167,11 +193,13 @@ def stats(self) -> dict: | |
| # ── internal ──────────────────────────────────────────────────── | ||
|
|
||
| @staticmethod | ||
| def _probe_vram() -> tuple[int, int]: | ||
| def _probe_vram() -> tuple[int, int] | None: | ||
| """Probe real-time free/total VRAM via nvidia-smi. | ||
|
|
||
| Returns ``(free_mb, total_mb)``, or ``(0, 0)`` when no | ||
| nvidia-smi is available or the probe fails. | ||
| Returns ``(free_mb, total_mb)``, or ``None`` when no nvidia-smi | ||
| is available or the probe fails. ``None`` (cannot know) is | ||
| deliberately distinct from ``(0, 0)`` (known-full): admission | ||
| fails open on ``None``, matching cluster claim_lease semantics. | ||
| """ | ||
| try: | ||
| from tinyagentos.system_stats import read_nvidia_vram | ||
|
|
@@ -183,4 +211,4 @@ def _probe_vram() -> tuple[int, int]: | |
| return free_mb, total_mb | ||
| except Exception: | ||
| logger.debug("vram-reservation: probe failed", exc_info=True) | ||
| return 0, 0 | ||
| return None | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[WARNING]:
variant.get("requires") or {}does not guard againstrequiresbeing a non-dict truthy value(variant.get("requires") or {})only falls back to{}when the value is falsy. Ifrequiresis present but a list/string (e.g. a malformed catalog variant — exactly the kind of untrusted external input this PR's theme defends against), the truthy value is kept and.get("backends")raisesAttributeError, 500-ing the download route. Guard withisinstanceinstead.Reply with
@kilocode-bot fix itto have Kilo Code address this issue.