cd /news/developer-tools/huggingface-s-large-file-downloads-k… · home topics developer-tools article
[ARTICLE · art-85429] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

HuggingFace's Large File Downloads Keep Stopping — Resuming with curl for Reliable Retrieval

A developer at Workstyle encountered stalled downloads of large model files from Hugging Face using huggingface_hub, and devised a workaround using curl's stagnation detection and automatic resumption. The solution also constructs a custom Hugging Face cache structure to enable offline model loading with HF_HUB_OFFLINE=1.

read4 min views1 publishedAug 4, 2026

📝 Originally published (in Japanese) at

[forge.workstyle.tech].

When developing a voice conversion app, I encountered an issue while trying to download the 44.1kHz Seed-VC model set (DiT weights, rmvpe, and BigVGAN vocoder) using huggingface_hub

.

When attempting to download models using

huggingface_hub

, the transfer would stop halfway through large files (hundreds of MB) and never progress.

While small config.json

files would download quickly, larger .pth

or .pt

files would get stuck at a certain point and freeze. This article describes how to use curl's stagnation detection and automatic resumption to ensure successful downloads, and create a custom Hugging Face cache structure to enable model reading even when HF_HUB_OFFLINE=1

.

On my machine, large file transfers using hf_hub_download

would stall halfway through. The suspected causes include IPv6 route unavailability and connection drops over extended periods. The issues are:

This isn't a matter of a slow network, but rather large transfers dying under specific conditions, so simply increasing the retry count won't solve the problem.

The appeal of huggingface_hub

lies in its cache management, not just as a down. load_custom_model_from_hf

and from_pretrained

assume a specific directory structure (blob entities + symbolic links + refs) and will re-download the model if this structure is broken.

To address this, I adopted a two-step approach:

hf_hub

)Metadata (etag, commit hash, size, and entity URL) can be retrieved from the huggingface_hub

API to construct the cache structure.

The key is combining curl options:

subprocess.run(
    ["curl", "-L", "--fail", "-C", "-",
     "--retry", "50", "--retry-delay", "3", "--retry-all-errors",
     "--speed-time", "20", "--speed-limit", "2000",   # 20 seconds at 2KB/s or lower, consider transfer failed and retry
     "-o", blob, loc],
    check=True,
)

The roles of each option are as follows:

--speed-time 20 --speed-limit 2000

-C -

--retry 50 --retry-delay 3 --retry-all-errors

— Retry after 3 seconds, up to 50 times. Transfers cut off by --speed-time

are also retried.-L

(follow redirects) and --fail

(non-zero exit on HTTP errors).This combination automatically loops through "stagnation → cut → resume" and eventually completes the transfer. This was the most reliable method in environments where large files would freeze.

The core of the Hugging Face cache (e.g., ~/.cache/huggingface/hub

) has the following structure per repository:

models--{org}--{repo}/
├── blobs/
│   └── {etag}                      # File entity, named by etag (content hash)
├── snapshots/
│   └── {commit_hash}/
│       └── {filename}              # Symbolic link to blob
└── refs/
    └── main                        # Branch name → commit hash text

The key points are:

blobs/

with etag namessnapshots/{commit}/

contains symbolic linksrefs/main

contains the commit hashrevision="main"

and allows hf_hub

to find the correct snapshot even when HF_HUB_OFFLINE=1

.Metadata can be obtained from the huggingface_hub

API:

from huggingface_hub import hf_hub_url, get_hf_file_metadata

url = hf_hub_url(repo_id, filename, revision=revision)
m = get_hf_file_metadata(url)
etag = (m.etag or "").strip('"')   # Becomes the blob file name
commit = m.commit_hash or revision # Becomes the snapshots/ directory name
size = m.size                       # Used for download completion detection
loc = m.location or url             # Entity URL (redirected)

The rest involves using curl to download the entity to blobs/{etag}

, creating a relative symbolic link from snapshots/{commit}/{filename}

, and writing the commit to refs/main

. The relative link ensures the cache remains intact even when moved to another machine.

os.symlink(os.path.relpath(blob, os.path.dirname(snap)), snap)
with open(os.path.join(refsdir, "main"), "w") as f:
    f.write(commit)

If the size is known, checking it against the existing blob size and skipping if complete can make re-runs idempotent.

Some repositories, like BigVGAN, contain large unnecessary files for inference (e.g., discriminator or optimizer states). Down the entire repository can result in getting stuck with the largest file. Specify the necessary files explicitly to avoid this.

Failing to create refs/main

alongside snapshots

and blobs

will prevent hf_hub

from resolving the correct commit when HF_HUB_OFFLINE=1

, even if the cache exists. Always create the three-part set (blob, snapshot link, and refs).

Even with a cache, hf_hub

performs a HEAD request at startup to check for updates (without re-down large files). To ensure complete offline functionality, set HF_HUB_OFFLINE=1

or TRANSFORMERS_OFFLINE=1

. Conversely, if you want to see updates but prevent downloads, you can leave it online and just allow HEAD requests.

hf_hub

transfers --speed-time

and --speed-limit

to -C -

with --retry

for resumption.blobs/{etag}

  • snapshots/{commit}/

with relative symbolic links + refs/main

).get_hf_file_metadata

.refs/main

is created to enable HF_HUB_OFFLINE=1

.

── more in #developer-tools 4 stories · sorted by recency
── more on @hugging face 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/huggingface-s-large-…] indexed:0 read:4min 2026-08-04 ·