ElBruno.HuggingFace.Downloader
1.4.2
dotnet add package ElBruno.HuggingFace.Downloader --version 1.4.2
NuGet\Install-Package ElBruno.HuggingFace.Downloader -Version 1.4.2
<PackageReference Include="ElBruno.HuggingFace.Downloader" Version="1.4.2" />
<PackageVersion Include="ElBruno.HuggingFace.Downloader" Version="1.4.2" />
<PackageReference Include="ElBruno.HuggingFace.Downloader" />
paket add ElBruno.HuggingFace.Downloader --version 1.4.2
#r "nuget: ElBruno.HuggingFace.Downloader, 1.4.2"
#:package ElBruno.HuggingFace.Downloader@1.4.2
#addin nuget:?package=ElBruno.HuggingFace.Downloader&version=1.4.2
#tool nuget:?package=ElBruno.HuggingFace.Downloader&version=1.4.2
๐ฅ ElBruno.HuggingFace.Downloader
A .NET library and CLI tool to download files (ONNX models, tokenizers, voice presets, etc.) from Hugging Face Hub repositories with progress reporting, caching, and authentication support.
Features
- ๐ฆ Download any file from public or private Hugging Face repositories
- ๐ Rich progress reporting with stages (Checking โ Downloading โ Validating โ Complete)
- ๐ HF_TOKEN authentication for gated/private repositories (env var or explicit)
- ๐ Atomic writes using temp files to avoid partial/corrupt downloads
- ๐ Resumable downloads using HTTP range requests for interrupted large files
- ๐ Revision pinning with resolved commit metadata and optional expected commit enforcement
- โ Required vs optional files โ optional files fail silently
- ๐งพ Manifest-based bundles with SHA-256 and size validation
- ๐ HEAD requests to resolve total download size before starting
- โญ๏ธ Skip existing files โ only downloads what's missing
- ๐ฅ๏ธ Cross-platform cache directory helpers (Windows, Linux, macOS)
- ๐ DI-friendly with
IServiceCollectionextension methods - ๐ ILogger integration for structured logging
๐ฆ NuGet Packages
| Package | Version | Downloads | Description |
|---|---|---|---|
| ElBruno.HuggingFace.Downloader | Core library for downloading files from Hugging Face Hub repositories | ||
| ElBruno.HuggingFace.Downloader.Cli | CLI tool (hfdownload) for managing Hugging Face downloads |
Installation
Library (NuGet)
dotnet add package ElBruno.HuggingFace.Downloader
CLI Tool
dotnet tool install -g ElBruno.HuggingFace.Downloader.Cli
Once installed, use the hfdownload command:
# Download model files
hfdownload download sentence-transformers/all-MiniLM-L6-v2 onnx/model.onnx tokenizer.json
# Download a specific tag into a revision-aware cache directory
hfdownload download sentence-transformers/all-MiniLM-L6-v2 onnx/model.onnx --revision v1.0
# Restart from scratch instead of resuming a preserved partial download
hfdownload download sentence-transformers/all-MiniLM-L6-v2 onnx/model.onnx --no-resume
# Ensure a manifest-defined bundle with integrity validation
hfdownload download --manifest ./phi4-bundle.json -o ./models/phi4
# Check if files exist locally
hfdownload check sentence-transformers/all-MiniLM-L6-v2 onnx/model.onnx tokenizer.json
# List cached models
hfdownload list
# Delete a cached model
hfdownload delete sentence-transformers/all-MiniLM-L6-v2
# See all commands
hfdownload --help
See the full CLI Reference for all commands and options.
Quick Start (Library)
1) Download model files
using ElBruno.HuggingFace;
using var downloader = new HuggingFaceDownloader();
var request = new DownloadRequest
{
RepoId = "sentence-transformers/all-MiniLM-L6-v2",
LocalDirectory = "./models/miniLM",
RequiredFiles = ["onnx/model.onnx", "tokenizer.json"],
OptionalFiles = ["tokenizer_config.json", "vocab.txt"],
Revision = "refs/pr/42"
};
await downloader.DownloadFilesAsync(request);
Console.WriteLine($"Resolved commit: {request.ResolvedCommitSha}");
2) Ensure a manifest-based bundle with SHA-256 validation
var manifest = new ModelBundleManifest
{
RepoId = "microsoft/Phi-4-mini-instruct-onnx",
Revision = "main",
Files =
[
new ModelBundleFile
{
Path = "onnx/model.onnx",
Size = 123456789,
Sha256 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
},
new ModelBundleFile
{
Path = "tokenizer.json",
Required = false
}
]
};
var bundle = await downloader.EnsureBundleAsync(manifest, "./models/phi4");
Console.WriteLine(bundle.ResolvedManifestPath);
Manifest-driven bundle downloads validate existing files before reuse, re-download corrupted files, and write a resolved manifest to ./models/phi4/.hf.bundle.resolved.json.
3) Pin a branch or tag to the expected commit
var request = new DownloadRequest
{
RepoId = "my-org/my-model",
LocalDirectory = "./models/pinned",
RequiredFiles = ["model.onnx"],
Revision = "main",
ExpectedCommitSha = "1234567890abcdef1234567890abcdef12345678"
};
await downloader.DownloadFilesAsync(request);
Console.WriteLine(request.ResolvedCommitSha);
4) Check if files are already downloaded
bool ready = downloader.AreFilesAvailable(
["onnx/model.onnx", "tokenizer.json"],
"./models/miniLM");
if (!ready)
{
var missing = downloader.GetMissingFiles(
["onnx/model.onnx", "tokenizer.json"],
"./models/miniLM");
Console.WriteLine($"Missing {missing.Count} files");
}
5) Track download progress
var progress = new Progress<DownloadProgress>(p =>
{
if (p.Stage == DownloadStage.Downloading)
Console.Write($"\rโฌ๏ธ [{p.CurrentFile}] {p.PercentComplete:F0}% (reused {ByteFormatHelper.FormatBytes(p.ResumedBytes)})");
else
Console.WriteLine($"{p.Stage}: {p.Message}");
});
await downloader.DownloadFilesAsync(new DownloadRequest
{
RepoId = "sentence-transformers/all-MiniLM-L6-v2",
LocalDirectory = "./models/miniLM",
RequiredFiles = ["onnx/model.onnx", "tokenizer.json"],
Progress = progress
});
6) Authentication (Private/Gated Repos)
Set the HF_TOKEN environment variable, or pass it explicitly:
var downloader = new HuggingFaceDownloader(new HuggingFaceDownloaderOptions
{
AuthToken = "hf_your_token_here"
});
7) Dependency Injection
builder.Services.AddHuggingFaceDownloader(options =>
{
options.Timeout = TimeSpan.FromMinutes(60);
});
// Then inject HuggingFaceDownloader in your services
public class MyModelService(HuggingFaceDownloader downloader)
{
public async Task EnsureModelAsync()
{
await downloader.DownloadFilesAsync(new DownloadRequest
{
RepoId = "my-org/my-model",
LocalDirectory = DefaultPathHelper.GetDefaultCacheDirectory("MyApp"),
RequiredFiles = ["model.onnx", "tokenizer.json"]
});
}
}
Direct downloads also write ./models/.../.hf.download.resolved.json so callers can inspect the requested revision and resolved commit later.
Documentation
| Topic | Description |
|---|---|
| Getting Started | Installation, all usage examples, and setup |
| CLI Reference | Complete CLI command reference |
| API Reference | Complete class and method documentation |
| Architecture | Design decisions, data flow, and project structure |
| Publishing | NuGet publishing with GitHub Actions |
Related Projects
- ElBruno.PersonaPlex โ Integrates this downloader to auto-download ONNX models for NVIDIA's PersonaPlex-7B-v1 full-duplex speech-to-speech model
Building from Source
git clone https://github.com/elbruno/ElBruno.HuggingFace.Downloader.git
cd ElBruno.HuggingFace.Downloader
dotnet build ElBruno.HuggingFace.Downloader.slnx
dotnet test ElBruno.HuggingFace.Downloader.slnx
Requirements
- .NET 8.0 SDK or later
๐ค Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License
This project is licensed under the MIT License โ see the LICENSE file for details.
๐ About the Author
Hi! I'm ElBruno ๐งก, a passionate developer and content creator exploring AI, .NET, and modern development practices.
Made with โค๏ธ by ElBruno
If you like this project, consider following my work across platforms:
- ๐ป Podcast: No Tienen Nombre โ Spanish-language episodes on AI, development, and tech culture
- ๐ป Blog: ElBruno.com โ Deep dives on embeddings, RAG, .NET, and local AI
- ๐บ YouTube: youtube.com/elbruno โ Demos, tutorials, and live coding
- ๐ LinkedIn: @elbruno โ Professional updates and insights
- ๐ X: @elbruno โ Quick tips, releases, and tech news
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
NuGet packages (11)
Showing the top 5 NuGet packages that depend on ElBruno.HuggingFace.Downloader:
| Package | Downloads |
|---|---|
|
ElBruno.LocalEmbeddings
Local embedding generation using Microsoft.Extensions.AI and ONNX Runtime |
|
|
ElBruno.Text2Image
A .NET library for local text-to-image generation using Stable Diffusion and ONNX Runtime. Supports multiple models (SD 1.5, LCM Dreamshaper) with automatic model download from HuggingFace and native C# inference โ no Python dependency. |
|
|
ElBruno.QwenTTS
Run Qwen3-TTS text-to-speech locally from C# using ONNX Runtime. Models download automatically from HuggingFace on first run. |
|
|
ElBruno.LocalLLMs
Local LLM chat completions using Microsoft.Extensions.AI and ONNX Runtime GenAI. IChatClient implementation for running LLMs locally. |
|
|
ElBruno.VibeVoiceTTS
A .NET library for VibeVoice text-to-speech using ONNX Runtime. Supports automatic model download from HuggingFace, voice presets, and native C# inference with no Python dependency. |
GitHub repositories
This package is not used by any popular GitHub repositories.