HuggingFace Model Downloader

bodaay · bodaay.hfdownloader

Simple go utility to download HuggingFace Models and Datasets

The HuggingFace Model Downloader is a utility tool for downloading models and datasets from the HuggingFace website. It offers multithreaded downloading for LFS files and ensures the integrity of downloaded models with SHA256 checksum verification.

winget install --id bodaay.hfdownloader --exact --source winget

Latest 3.0.4

Release Notes

What's Changed in v3.0.4 Bug-fix release tackling eight open issues reported against v3.0.3. Focused on download correctness, webui responsiveness, storage flexibility, and analyzer coverage for new quant formats. Every fix ships with regression tests; go test -race ./... is now fully green across every package. Bug Fixes

  • Resumable downloads actually resume now (#70) — downloadSingle and each downloadMultipart part goroutine now open .part files with O_RDWR|O_CREATE (no truncate), stat the existing size, and issue Range: bytes=pos-end requests from that offset. Interrupted downloads resume correctly on rerun, and within-process retries after a flaky-connection cut no longer lose bytes. Previously every Ctrl+C silently re-fetched from zero and single-file downloads literally had no resume code path at all.
  • Unsloth Dynamic quant variants correctly labeled (#72) — the GGUF quant regex now supports Q{2..8}_K_XL / _XXL suffixes and IQ1_S / IQ1_M. Previously on repos like unsloth/Qwen3-30B-A3B-GGUF the regex silently collapsed six UD-Q*_K_XL files into Q2_K..Q8_K labels that collided with the real plain-K quants, and missed the two IQ1 files entirely. All 25 GGUF files in that repo now label correctly. Added quality/description map entries for Q2_K_L, Q2..8_K_XL, IQ1_S/M, IQ2_M, IQ3_XXS.
  • Multimodal GGUF repos auto-bundle the vision encoder (#76) — analyzeGGUF now partitions .gguf files into LLM quants vs mmproj vision encoders. A vision_encoder SelectableItem is emitted as Recommended by default, so the recommended CLI command for a multimodal repo becomes e.g. -F q4_k_m,mmproj-f16 for unsloth/gemma-3-4b-it-GGUF. Downloading a single quant now pulls in the matching projector automatically, matching LM Studio's behavior.
  • Progress no longer oscillates on slow/flaky connections (#75) — the multipart progress ticker now stops cleanly before assembly via an explicit done channel + WaitGroup, and an explicit final full-size reading is emitted after all parts complete. Root cause: the ticker kept stating part files while assembly was deleting them, emitting downloaded=0 events that made the UI appear stuck at 2.4% ↔ 2.5% for hours on slow links. Combined with the #70 fix above, flaky downloads of multi-GB files now converge cleanly.
  • Pause no longer claims the file is 100% done — fixed a regression in the #75 tail path where downloadMultipart on cancellation would fall past its errCh drain (cancelled goroutines return silently via sleepCtx without pushing errors) and emit a bogus downloaded == total event followed by assembly over an incomplete part set — corrupting the final file and deleting the very partial bytes the next resume was supposed to continue from. Now bails out with ctx.Err() immediately after the ticker shutdown. Regression test in TestDownloadMultipart_CancelMidStreamDoesNotClaim100.
  • Web UI no longer floods the browser with updates (#62) — two-layer fix:
    • Server-side 250ms per-job WebSocket broadcast coalescer in front of BroadcastJob. Progress events arriving inside the window collapse to a single flush of the latest state; terminal status changes (completed/failed/cancelled/paused) bypass the gate so pause/cancel transitions still feel instant.
    • Frontend renderJobs no longer does container.innerHTML = jobs.map(...).join('') on every tick. Per-job DOM elements are cached and updated in place — progress bar width and stats text change, but the card node, the action buttons, and their event listeners stay stable. Hover states persist and Pause/Cancel buttons are clickable during an active download.
  • Dismissed jobs stay dismissed across refresh (#68) — new POST /api/jobs/{id}/dismiss endpoint permanently removes a terminal-state job from the manager. Frontend dismissJob now calls the server before removing from local state, so page reloads and WebSocket reconnects don't repopulate it. Attempts to dismiss queued or running jobs return 409. The primary per-file-deletion ask in the same issue is tracked separately.
  • JobManager returns snapshots — data race fixed — CreateJob, GetJob, ListJobs, and the internal WebSocket broadcast path all now return/forward cloned Job snapshots via a new cloneJobLocked helper. Previously the HTTP JSON encoder and the WS broadcaster would read Job fields while runJob was mutating them on a separate goroutine. go test -race ./... is now fully green across every package for the first time. Features
  • --local-dir CLI flag (#71, #73) — new flag mirroring huggingface-cli download --local-dir. Downloads real files into the chosen directory instead of the HF cache's blobs+symlinks layout. Right choice for feeding weights to llama.cpp / ollama, Windows users without Developer Mode, and NFS/SMB/USB transfers. Equivalent to the existing --legacy -o form — both spellings are permanent and interchangeable, and --legacy is no longer marked for removal.
  • Installer defaults to ~/.local/bin — no more sudo prompt (#69) — the one-liner bash <(curl -sSL https://g.bodaay.io/hfd) install now picks a user-local install path in this order:
    1. ~/.local/bin if already in PATH
    2. ~/bin if already in PATH
    3. /usr/local/bin if writable
    4. Fallback to ~/.local/bin with a printed export PATH= line Explicit targets like install /usr/local/bin still work and still use sudo where needed. Root users still get /usr/local/bin by default. Documentation
  • README now has a prominent Storage Modes section documenting both HF-cache-default and flat-file --local-dir modes as first-class, permanent options with when-to-use-which guidance.
  • docs/CLI.md and docs/V3_FEATURES.md updated to reflect the un-deprecated --legacy / --output flags and the new --local-dir spelling. Test Infrastructure
  • TestAPI_Health no longer pins to a stale hardcoded version string.
  • TestJobManager_CreateJob no longer races its TempDir cleanup against in-flight runJob goroutines — new JobManager.WaitAll(timeout) lets the test block on actual goroutine exit before cleanup runs. Full Changelog: https://github.com/bodaay/HuggingFaceModelDownloader/compare/v3.0.3...v3.0.4

Installer type: portable

Architecture Scope Download SHA256
x64 Download B6CA755E68B5EC21041A542E75A146A47D2964C519998505CC4CD212496D2D34

Details

Homepage
https://github.com/bodaay/HuggingFaceModelDownloader
License
Apache-2.0
Publisher
bodaay
Support
https://github.com/bodaay/HuggingFaceModelDownloader/issues
Moniker
hfdownloader

Tags

huggingface

Older versions (9)

3.0.3
Architecture Scope Download SHA256
x64 Download 13A78637EA43412D1B53AD093FD4FB2EEC0AF6DC5AB019A3EB73DA1DBC3E1B4C
3.0.1
Architecture Scope Download SHA256
x64 Download 2E577B2C33BB92D74758D0D98D8E4CC64F03C34C8A77B31FD217B02E008B6855
3.0.0
Architecture Scope Download SHA256
x64 Download 8FBEB80B90135315955D9E362853EA354068241817533B991A6302CBEB802988
2.3.4
Architecture Scope Download SHA256
x64 Download 2115E3A4C395DBC37F76FBA2E6DD5FED81A922B10E0FF13C163E532187B205D3
2.3.3
Architecture Scope Download SHA256
x64 Download 6352DD10C47B2BBB518F5C2135499C3F907BD6E9623681B435F7B16122021A29
2.3.1
Architecture Scope Download SHA256
x64 Download CBE24A568E757D3902DC12D85D1E49AD669A7147CDFD2A783B067ACF935E3AC0
2.3.0
Architecture Scope Download SHA256
x64 Download D3D1D4236AF63491EEB33A039BA55B049132F8A4F126A80198BBFE91AB6D0B51
2.0.0
Architecture Scope Download SHA256
x64 Download 17623348A58057D3F039DD118556A9952FA028AAC7D8B799DA90E57A5E99CE4A
1.4.2
Architecture Scope Download SHA256
x64 Download 2F8E7CF368B379E0F93200E2005B9B1CD34E1FD6863EDC9ECB6BECC7A721BE93