studio: fix download progress -- track per-variant, include incomplete blobs
1. Progress endpoint now takes a variant parameter and only counts .gguf files matching that variant (not all files in the repo cache, which would include previously downloaded variants) 2. Tracks .incomplete files in HF blobs dir for in-progress single-shard downloads, capping at 99% until the file is fully committed 3. Fixed loading text: "Loading model..." for cached, "Downloading model..." for new downloads, with appropriate descriptions 4. Wording: "Downloading and loading model. Large models can take a while." instead of "This may include downloading."
This commit is contained in:
parent
b1dda44745
commit
1dfba866be
3 changed files with 25 additions and 12 deletions
|
|
@ -607,10 +607,15 @@ async def get_gguf_variants(
|
|||
@router.get("/gguf-download-progress")
|
||||
async def get_gguf_download_progress(
|
||||
repo_id: str = Query(..., description = "HuggingFace repo ID"),
|
||||
variant: str = Query("", description = "Quantization variant (e.g. UD-TQ1_0)"),
|
||||
expected_bytes: int = Query(0, description = "Expected total download size in bytes"),
|
||||
current_subject: str = Depends(get_current_subject),
|
||||
):
|
||||
"""Return download progress by checking current size of cached GGUF files."""
|
||||
"""Return download progress by checking cached GGUF files for a specific variant.
|
||||
|
||||
Tracks completed shard downloads in snapshots and in-progress downloads
|
||||
in the blobs directory (incomplete files).
|
||||
"""
|
||||
import re as _re
|
||||
|
||||
try:
|
||||
|
|
@ -625,25 +630,31 @@ async def get_gguf_download_progress(
|
|||
|
||||
cache_dir = Path(hf_constants.HF_HUB_CACHE)
|
||||
target = f"models--{repo_id.replace('/', '--')}".lower()
|
||||
variant_lower = variant.lower().replace("-", "").replace("_", "")
|
||||
downloaded_bytes = 0
|
||||
in_progress_bytes = 0
|
||||
for entry in cache_dir.iterdir():
|
||||
if entry.name.lower() == target:
|
||||
# Sum .gguf files in snapshots + incomplete downloads in blobs
|
||||
# Count completed .gguf files matching this variant in snapshots
|
||||
for f in entry.rglob("*.gguf"):
|
||||
downloaded_bytes += f.stat().st_size
|
||||
# Also check incomplete downloads (blobs without extension)
|
||||
fname = f.name.lower().replace("-", "").replace("_", "")
|
||||
if not variant_lower or variant_lower in fname:
|
||||
downloaded_bytes += f.stat().st_size
|
||||
# Check blobs for in-progress downloads (.incomplete files)
|
||||
blobs_dir = entry / "blobs"
|
||||
if blobs_dir.is_dir():
|
||||
for f in blobs_dir.iterdir():
|
||||
if f.is_file():
|
||||
downloaded_bytes += f.stat().st_size
|
||||
if f.is_file() and f.name.endswith(".incomplete"):
|
||||
in_progress_bytes += f.stat().st_size
|
||||
break
|
||||
|
||||
progress = (
|
||||
min(downloaded_bytes / expected_bytes, 1.0) if expected_bytes > 0 else 0
|
||||
)
|
||||
total_progress_bytes = downloaded_bytes + in_progress_bytes
|
||||
progress = min(total_progress_bytes / expected_bytes, 0.99) if expected_bytes > 0 else 0
|
||||
# Only report 1.0 when all bytes are in completed files (not in-progress)
|
||||
if expected_bytes > 0 and downloaded_bytes >= expected_bytes:
|
||||
progress = 1.0
|
||||
return {
|
||||
"downloaded_bytes": downloaded_bytes,
|
||||
"downloaded_bytes": total_progress_bytes,
|
||||
"expected_bytes": expected_bytes,
|
||||
"progress": round(progress, 3),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,10 +105,12 @@ export interface CachedGgufRepo {
|
|||
|
||||
export async function getGgufDownloadProgress(
|
||||
repoId: string,
|
||||
variant: string,
|
||||
expectedBytes: number,
|
||||
): Promise<{ downloaded_bytes: number; expected_bytes: number; progress: number }> {
|
||||
const params = new URLSearchParams({
|
||||
repo_id: repoId,
|
||||
variant,
|
||||
expected_bytes: String(expectedBytes),
|
||||
});
|
||||
const response = await authFetch(`/api/models/gguf-download-progress?${params}`);
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ export function useChatModelRuntime() {
|
|||
extraLoadingDescription ?? null,
|
||||
isDownloaded
|
||||
? "Loading cached model into memory."
|
||||
: "This may include downloading. Large models can take a while.",
|
||||
: "Downloading and loading model. Large models can take a while.",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
|
@ -320,7 +320,7 @@ export function useChatModelRuntime() {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
const prog = await getGgufDownloadProgress(modelId, expectedBytes);
|
||||
const prog = await getGgufDownloadProgress(modelId, ggufVariant ?? "", expectedBytes);
|
||||
if (prog.progress > 0 && prog.progress < 1) {
|
||||
const dlGb = prog.downloaded_bytes / (1024 ** 3);
|
||||
const totalGb = prog.expected_bytes / (1024 ** 3);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue