livehl/aimirrorPublic

๐Ÿš€ 200ๅ€้€Ÿ๏ผAIๆ—ถไปฃ็š„ไธ‹่ฝฝ็ฅžๅ™จ | Docker/PyPI/HuggingFace/CRAN ๅ…จๅŠ ้€Ÿ | ๅนถ่กŒๅˆ†็‰‡+ๆ™บ่ƒฝ็ผ“ๅญ˜๏ผŒ่ฎฉไธ‹่ฝฝ้ฃž่ตทๆฅ

AI summary: A smart, parallel-download proxy that accelerates PyPI, Docker, and HuggingFace in restricted networks.

Stars
211
+1 today
Forks
20
Watchers
2
Open issues
1
Open PRs
0
Contributors
~1
Commits
51
Branches
1

PythonMITCreated Mar 5, 2026Last push 4mo agoLatest release v0.3.4+1 stars this week+1 this month

Star history

since Mar 1, 2026
0100200Mar 2026Apr 2026Jun 2026Aug 2026
211 stars as of Aug 7, 2026, tracked back to Mar 1, 2026. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulAugMonWedFri2025-08-09: 0 commits2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 0 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 0 commits2026-02-14: 0 commits2026-02-15: 0 commits2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 0 commits2026-02-25: 0 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 0 commits2026-03-03: 0 commits2026-03-04: 0 commits2026-03-05: 5 commits2026-03-06: 17 commits2026-03-07: 11 commits2026-03-08: 0 commits2026-03-09: 0 commits2026-03-10: 6 commits2026-03-11: 0 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 3 commits2026-03-15: 9 commits2026-03-16: 0 commits2026-03-17: 0 commits2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 0 commits2026-03-24: 0 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 0 commits2026-04-04: 0 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 0 commits2026-04-10: 0 commits2026-04-11: 0 commits2026-04-12: 0 commits2026-04-13: 0 commits2026-04-14: 0 commits2026-04-15: 0 commits2026-04-16: 0 commits2026-04-17: 0 commits2026-04-18: 0 commits2026-04-19: 0 commits2026-04-20: 0 commits2026-04-21: 0 commits2026-04-22: 0 commits2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 0 commits2026-04-26: 0 commits2026-04-27: 0 commits2026-04-28: 0 commits2026-04-29: 0 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 0 commits2026-05-07: 0 commits2026-05-08: 0 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 0 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 0 commits2026-06-05: 0 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 0 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 0 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 0 commits2026-07-04: 0 commits2026-07-05: 0 commits2026-07-06: 0 commits2026-07-07: 0 commits2026-07-08: 0 commits2026-07-09: 0 commits2026-07-10: 0 commits2026-07-11: 0 commits2026-07-12: 0 commits2026-07-13: 0 commits2026-07-14: 0 commits2026-07-15: 0 commits2026-07-16: 0 commits2026-07-17: 0 commits2026-07-18: 0 commits2026-07-19: 0 commits2026-07-20: 0 commits2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 0 commits2026-07-25: 0 commits2026-07-26: 0 commits2026-07-27: 0 commits2026-07-28: 0 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 0 commits2026-08-01: 0 commits2026-08-02: 0 commits2026-08-03: 0 commits2026-08-04: 0 commits2026-08-05: 0 commits2026-08-06: 0 commits2026-08-07: 0 commits2026-08-08: 0 commits
51 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Permissive license

    MIT

  • Continuous integration

    Automated checks passing

What aimirror does

aimirror is a specialized high-performance cache and proxy designed to rescue AI engineers trapped behind slow corporate networks. It acts as a unified accelerator for multiple package managers (pip, docker pull, huggingface-cli). Instead of just caching, it intercepts requests, dynamically routes large files, and executes multi-threaded HTTP Range parallel downloads to saturate available bandwidth. It automatically rewrites HTML/JSON responses to seamlessly spoof clients, providing up to 200x speedups on large machine learning artifacts without requiring users to change their workflows.

aimirror is essential for AI engineers, data scientists, and DevOps teams dealing with massive machine learning dependencies over constrained or highly-latent network connections.

  • Parallel Chunking: Forces single-threaded tools like pip to download large wheel files using multi-threaded HTTP Range requests.
  • Unified Endpoint: One service accelerates PyPI, Docker Hub, CRAN, and HuggingFace simultaneously.
  • Intelligent LRU Cache: Deduplicates files based on digest hashes rather than just URLs, optimizing local disk usage.
  • Response Rewriting: Automatically modifies links in JSON/HTML API responses so clients natively use the proxy.
  • Custom Handlers: Includes specialized logic to navigate complex authentication and manifest workflows like Docker Registries.

Where teams use it

Corporate Intranet Bypassing

Engineers on throttled VPNs can download gigabyte-sized PyTorch wheels in seconds instead of hours.

Team Caching

Deploying aimirror on a local network server so a team only downloads massive HuggingFace models from the internet once.

CI/CD Acceleration

Speeding up automated build pipelines that repeatedly pull the same bloated CUDA Docker layers.

Multi-Source Mirroring

Configuring custom routing rules to accelerate niche or internal HTTP endpoints without writing new proxy logic.

Getting started: Check the documentation for docker-compose deployment.

README

main branch

๐Ÿš€ aimirror

Python FastAPI License PyPI

AI ๆ—ถไปฃ็š„ไธ‹่ฝฝ้•œๅƒๅŠ ้€Ÿๅ™จ โ€”โ€” ่ขซๆ…ข้€Ÿ็ฝ‘็ปœ้€ผ็–ฏ็š„ๅทฅ็จ‹ๅธˆ็š„่‡ชๆ•‘ๅทฅๅ…ท

ไธ€ไธชๆœๅŠก = PyPI + Docker Hub + CRAN + HuggingFace ๅ…จๅŠ ้€Ÿ๏ผŒ่ฟ˜่ƒฝไปปๆ„ๆ‰ฉๅฑ•ๆ›ดๅคšๆบ

๐Ÿ’ก ้กน็›ฎ่ƒŒๆ™ฏ

ไฝœไธบไธ€ๅ AI ๅทฅ็จ‹ๅธˆ๏ผŒๆฏๅคฉ็š„ๅทฅไฝœ็ฆปไธๅผ€๏ผš

  • pip install torch โ€”โ€” ๅ‡ ็™พ MB ็š„ wheel ๅŒ…ไธ‹่ฝฝๅˆฐๅœฐ่€ๅคฉ่’
  • docker pull nvidia/cuda โ€”โ€” ๅ‡ ไธช GB ็š„้•œๅƒๅฑ‚ๅๅคไธ‹่ฝฝ
  • huggingface-cli download โ€”โ€” ๆจกๅž‹ๆ–‡ไปถไปŽ HuggingFace ่œ—็‰›่ˆฌ็ˆฌ่ฟ‡ๆฅ

ๅ…ฌๅธๅ†…็ฝ‘ๆœ‰ไปฃ็†๏ผŒไฝ†ๅ•็บฟ็จ‹ไธ‹่ฝฝๅคงๆ–‡ไปถไพ็„ถๆ…ขๅพ—่ฎฉไบบๅดฉๆบƒใ€‚้‡ๅคไธ‹่ฝฝ็›ธๅŒ็š„ๅŒ…๏ผŸไธๅญ˜ๅœจ็š„็ผ“ๅญ˜ใ€‚ๅฟๆ— ๅฏๅฟ๏ผŒไบŽๆ˜ฏๅ†™ไบ†่ฟ™ไธชๅทฅๅ…ทใ€‚

aimirror = ๆ™บ่ƒฝ่ทฏ็”ฑ + ๅนถ่กŒๅˆ†็‰‡ไธ‹่ฝฝ + ๆœฌๅœฐ็ผ“ๅญ˜๏ผŒ่ฎฉไธ‹่ฝฝ้€Ÿๅบฆ้ฃž่ตทๆฅใ€‚

โœจ ๅŠŸ่ƒฝ็‰นๆ€ง

  • โšก ๅนถ่กŒไธ‹่ฝฝ โ€”โ€” HTTP Range ๅˆ†็‰‡๏ผŒๅคš็บฟ็จ‹ๅนถๅ‘๏ผŒๆฆจๅนฒๅธฆๅฎฝ
  • ๐Ÿ’พ ๆ™บ่ƒฝ็ผ“ๅญ˜ โ€”โ€” ๅŸบไบŽๆ–‡ไปถ digest ๅŽป้‡๏ผŒLRU ่‡ชๅŠจๆท˜ๆฑฐ
  • ๐ŸŽฏ ๅŠจๆ€่ทฏ็”ฑ โ€”โ€” ๅฐๆ–‡ไปถ็›ดๆŽฅไปฃ็†๏ผŒๅคงๆ–‡ไปถ่‡ชๅŠจๅนถ่กŒ
  • ๐Ÿ”— ๅคšๆบๆ”ฏๆŒ โ€”โ€” Docker Hubใ€PyPIใ€CRANใ€HuggingFace ๅผ€็ฎฑๅณ็”จ
  • ๐Ÿ”Œ ไปปๆ„ๆ‰ฉๅฑ• โ€”โ€” ๅช่ฆๆ˜ฏ HTTP ไธ‹่ฝฝ๏ผŒ้…็ฝฎไธ€ๆก่ง„ๅˆ™ๅณๅฏๅ‡ ๅๅ€ๅŠ ้€Ÿ
  • ๐Ÿ“ ๅ†…ๅฎนๆ”นๅ†™ โ€”โ€” ่‡ชๅŠจๆ”นๅ†™ HTML/JSON ๅ“ๅบ”ไธญ็š„้“พๆŽฅ๏ผŒๆ— ็ผไปฃ็†
  • ๐ŸŽ›๏ธ ็‰นๆฎŠๅค„็† โ€”โ€” ๆ”ฏๆŒ่‡ชๅฎšไน‰ Handler ๅค„็†ๅคๆ‚ๅœบๆ™ฏ๏ผˆๅฆ‚ Docker Registry๏ผ‰
  • ๐Ÿšฆ ๅนถๅ‘ๆŽงๅˆถ โ€”โ€” ๅ…จๅฑ€ไธ‹่ฝฝๅนถๅ‘้™ๅˆถ๏ผŒ้˜ฒๆญข่ต„ๆบ่€—ๅฐฝ
  • ๐Ÿ”„ ่ทฏๅพ„้‡ๅ†™ โ€”โ€” ็ตๆดป็š„่ทฏๅพ„ๆ›ฟๆข่ง„ๅˆ™๏ผŒ้€‚้…ๅ„็ง API ๅทฎๅผ‚
  • ๐Ÿ”‘ ็ผ“ๅญ˜ไผ˜ๅŒ– โ€”โ€” ๆ”ฏๆŒๅŽŸๅง‹ URL ไฝœไธบ็ผ“ๅญ˜ key๏ผŒ่งฃๅ†ณไธดๆ—ถ็ญพๅ้—ฎ้ข˜

๐Ÿ”ฅ ๆ€ง่ƒฝๅฎžๆต‹

PyPI ๅŒ…ๅฎ‰่ฃ…ๅŠ ้€Ÿๅฏนๆฏ”

ไฝฟ็”จ uv pip install ๅฎ‰่ฃ… 148 ไธชไพ่ต–ๅŒ…๏ผˆๅซ torchใ€transformers ็ญ‰ๅคงๅŒ…๏ผ‰๏ผš

ๆจกๅผ ่งฃๆžไพ่ต– ๅ‡†ๅค‡ๅŒ… ๆ€ป่€—ๆ—ถ ๅŠ ้€Ÿๆฏ”
โŒ ไป…ไปฃ็† (900KB/s) 17m 04s 14m 20s ~31 ๅˆ†้’Ÿ 1x
โœ… aimirror (170MB/s) 34.78s 45.81s ~80 ็ง’ 23x

๐Ÿ’ก ๅฎžๆต‹็Žฏๅขƒ: ๅ…ฌๅธๅ†…็ฝ‘ไปฃ็†๏ผŒๅธฆๅฎฝ็“ถ้ขˆๆ˜Žๆ˜พใ€‚ไฝฟ็”จ aimirror ๅŽไปŽ 900KB/s ้ฃ™ๅ‡่‡ณ 170MB/s๏ผŒๆ้€Ÿ่ฟ‘ 200 ๅ€๏ผ

็ผ“ๅญ˜ๆ•ˆๆžœ

ๅœบๆ™ฏ ่€—ๆ—ถ ้€Ÿๅบฆ ่ฏดๆ˜Ž
้ฆ–ๆฌกไธ‹่ฝฝ 80s 170MB/s ๅนถ่กŒไธ‹่ฝฝ + ๅ†™ๅ…ฅ็ผ“ๅญ˜
็ผ“ๅญ˜ๅ‘ฝไธญ <1s 3000+ MB/s ไธ‡ๅ…†ๅ†…็ฝ‘ๅฎžๆต‹๏ผŒๆœฌๅœฐ SSD ๆ›ดๅฟซ๏ผŒ็žฌๅผ€

ๅคšๆบๅŒๆ—ถๅŠ ้€Ÿ

ไธ€ไธช aimirror ๆœๅŠก๏ผŒๅŒๆ—ถๅŠ ้€Ÿๅคš็งๅŒ…็ฎก็†ๅ™จ๏ผš

ๅŒ…็ฎก็†ๅ™จ ้…็ฝฎๆ–นๅผ ๅŠ ้€Ÿๆ•ˆๆžœ
pip/uv export HTTPS_PROXY=http://localhost:8081 ๆˆ– pip install -i http://localhost:8081/simple PyPI ๅŒ… 23x ๅŠ ้€Ÿ
docker /etc/docker/daemon.json ไธญ่ฎพ็ฝฎ registry-mirrors ้•œๅƒๆ‹‰ๅ–ๅนถ่กŒๅˆ†็‰‡
R CRAN options(repos = c(CRAN = "http://localhost:8081")) R ๅŒ…ไธ‹่ฝฝๅŠ ้€Ÿ
huggingface-cli export HF_ENDPOINT=http://localhost:8081 ๆจกๅž‹ๆ–‡ไปถ็ง’ไธ‹
conda .condarc ไธญ้…็ฝฎ channels ๅŒ็†ๅฏๆ‰ฉๅฑ•
npm/maven ้…็ฝฎ registry ๆŒ‡ๅ‘ aimirror ไปปๆ„ HTTP ๆบๅ‡ๅฏ

๐Ÿ”Œ ๆ‰ฉๅฑ•่ƒฝๅŠ›: ๅช่ฆๆ˜ฏ HTTP ไธ‹่ฝฝ๏ผŒๅœจ config.yaml ไธญๆทปๅŠ ไธ€ๆก่ง„ๅˆ™ๅณๅฏๆŽฅๅ…ฅๅŠ ้€Ÿ๏ผŒๆ— ้œ€ๅฏๅŠจๅคšไธชๆœๅŠกใ€‚

๐Ÿ—๏ธ ๆžถๆž„

flowchart LR
    subgraph Client["ๅฎขๆˆท็ซฏ"]
        PIP[pip install]
        DOCKER[docker pull]
        HF[huggingface-cli]
        R[R install.packages]
    end

    subgraph aimirror["aimirror ๆœๅŠก"]
        ROUTER[่ทฏ็”ฑๅŒน้…ๅ™จ<br/>router.py]
        HANDLER[็‰นๆฎŠๅค„็†ๅ™จ<br/>handlers/]
        PROXY[็›ดๆŽฅไปฃ็†<br/>proxy]
        DOWNLOADER[ๅนถ่กŒไธ‹่ฝฝๅ™จ<br/>downloader.py]
        CACHE[็ผ“ๅญ˜็ฎก็†ๅ™จ<br/>cache.py]
        REWRITE[ๅ†…ๅฎนๆ”นๅ†™<br/>content_rewrite]
    end

    subgraph UpstreamProxy["ไธŠๆธธไปฃ็† (ๅฏ้€‰)"]
        COMPANY_PROXY[ๅ…ฌๅธไปฃ็†]
    end

    subgraph Upstream["ไธŠๆธธๆœๅŠก"]
        PYPI[PyPI]
        DOCKER_HUB[Docker Hub]
        HF_HUB[HuggingFace]
        CRAN[CRAN]
    end

    PIP --> ROUTER
    DOCKER --> ROUTER
    HF --> ROUTER
    R --> ROUTER

    ROUTER -->|ๅŒน้… handler| HANDLER
    ROUTER -->|ๅฐๆ–‡ไปถ/ไปฃ็†็ญ–็•ฅ| PROXY
    ROUTER -->|ๅคงๆ–‡ไปถ/ๅนถ่กŒ็ญ–็•ฅ| DOWNLOADER

    HANDLER --> PROXY
    PROXY -->|้œ€่ฆๆ”นๅ†™| REWRITE
    REWRITE --> Client
    PROXY -->|็›ดๆŽฅ่ฟ”ๅ›ž| Client
    
    DOWNLOADER --> CACHE
    CACHE -->|ๅ‘ฝไธญ| Client
    CACHE -->|ๆœชๅ‘ฝไธญ| UpstreamProxy
    PROXY --> UpstreamProxy

    UpstreamProxy -.->|ๅฏ้€‰| Upstream
    UpstreamProxy -->|็›ด่ฟž| Upstream

    DOCKER_HUB -->|่ฟ”ๅ›žๆ–‡ไปถ| CACHE
    PYPI -->|่ฟ”ๅ›žๆ–‡ไปถ| CACHE
    HF_HUB -->|่ฟ”ๅ›žๆ–‡ไปถ| CACHE
    CRAN -->|่ฟ”ๅ›žๆ–‡ไปถ| CACHE
Loading

๐Ÿš€ ๅฟซ้€Ÿๅผ€ๅง‹

ๆ–นๅผไธ€๏ผšpip ๅฎ‰่ฃ…๏ผˆๆŽจ่๏ผ‰

# ๅฎ‰่ฃ…
pip install aimirror

# ๅฏๅŠจ
aimirror

# ไฝฟ็”จ
curl http://localhost:8081/health

ๆ–นๅผไบŒ๏ผšๆบ็ ๅฎ‰่ฃ…

# ๅ…‹้š†ไป“ๅบ“
git clone https://github.com/livehl/aimirror.git
cd aimirror

# ๅฎ‰่ฃ…ไพ่ต–
pip install -r requirements.txt

# ๅฏๅŠจ
python main.py

# ไฝฟ็”จ
curl http://localhost:8081/health

๐Ÿ”ง ๅฎขๆˆท็ซฏ้…็ฝฎ

pip / uv

# ไธดๆ—ถไฝฟ็”จ๏ผˆๅ•ๆฌกๅฎ‰่ฃ…๏ผ‰
pip install torch --index-url http://localhost:8081/simple --trusted-host localhost:8081

# ๅ…จๅฑ€้…็ฝฎ๏ผˆๆŽจ่๏ผ‰
pip config set global.index-url http://localhost:8081/simple
pip config set global.trusted-host localhost:8081

# ไฝฟ็”จ uv๏ผˆ้€Ÿๅบฆๆ›ดๅฟซ๏ผ‰
uv pip install torch --index-url http://localhost:8081/simple

# ๆˆ–ไฝฟ็”จ็Žฏๅขƒๅ˜้‡
export HTTPS_PROXY=http://localhost:8081
pip install torch

Docker

# ้…็ฝฎ daemon.json
sudo tee /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["http://localhost:8081"]
}
EOF
sudo systemctl restart docker

# ๆˆ–ไธดๆ—ถๆ‹‰ๅ–
docker pull --registry-mirror=http://localhost:8081 nginx

โš ๏ธ ้‡่ฆๆ็คบ๏ผšDocker ้•œๅƒๅฑ‚ๆ–‡ไปถ้€šๅธธๅพˆๅคง๏ผˆGB ็บงๅˆซ๏ผ‰๏ผŒๅปบ่ฎฎๅฐ† chunk_size ่ฎพ็ฝฎไธบ 0๏ผˆ่‡ชๅŠจๆจกๅผ๏ผ‰ใ€‚

่‡ชๅŠจๆจกๅผไธ‹๏ผŒchunk_size = ๆ–‡ไปถๆ€ปๅคงๅฐ / concurrency๏ผŒ่ฟ™ๆ ทๅฏไปฅ๏ผš

  • ้ฟๅ…ๅ›บๅฎšๅฐๅˆ†็‰‡ๅฏผ่‡ดๅˆ†็‰‡ๆ•ฐ้‡่ฟ‡ๅคš
  • ๅ‡ๅฐ‘ Docker Registry token ๅ› ่ถ…ๆ—ถๅคฑๆ•ˆ็š„ๆฆ‚็އ
  • ไฟๆŒๅนถๅ‘ๆ•ฐไธๅ˜๏ผŒๅŒๆ—ถไผ˜ๅŒ–ๅˆ†็‰‡ๅคงๅฐ

้…็ฝฎ็คบไพ‹่ง config.yaml ไธญ็š„ docker-blob ่ง„ๅˆ™ใ€‚

HuggingFace (huggingface-cli)

# ่ฎพ็ฝฎ็Žฏๅขƒๅ˜้‡
export HF_ENDPOINT=http://localhost:8081

# ไธ‹่ฝฝๆจกๅž‹๏ผˆๆ”ฏๆŒๆ‰€ๆœ‰ๆ–‡ไปถ็ฑปๅž‹๏ผš.gguf, .bin, .safetensors, .json ็ญ‰๏ผ‰
huggingface-cli download TheBloke/Llama-2-7B-GGUF llama-2-7b.Q4_K_M.gguf

# ไธ‹่ฝฝๆ•ดไธชไป“ๅบ“
huggingface-cli download meta-llama/Llama-2-7b-hf --local-dir ./models

ๆˆ–ไฝฟ็”จ Python:

import os
os.environ["HF_ENDPOINT"] = "http://localhost:8081"

from huggingface_hub import hf_hub_download, snapshot_download

# ไธ‹่ฝฝๅ•ไธชๆ–‡ไปถ
hf_hub_download(repo_id="TheBloke/Llama-2-7B-GGUF", filename="llama-2-7b.Q4_K_M.gguf")

# ไธ‹่ฝฝๆ•ดไธชไป“ๅบ“
snapshot_download(repo_id="meta-llama/Llama-2-7b-hf", local_dir="./models")

R (CRAN)

# ๅœจ R ๆŽงๅˆถๅฐไธญ่ฎพ็ฝฎ
options(repos = c(CRAN = "http://localhost:8081"))

# ๆˆ–ๅœจ .Rprofile ไธญๆฐธไน…้…็ฝฎ
cat('options(repos = c(CRAN = "http://localhost:8081"))\n', file = "~/.Rprofile")

Conda

# ไฟฎๆ”น .condarc
cat >> ~/.condarc <<EOF
channels:
  - http://localhost:8081/conda-forge
  - http://localhost:8081/bioconda
EOF

npm / yarn

# ไธดๆ—ถไฝฟ็”จ
npm install --registry http://localhost:8081/registry/npm

# ๅ…จๅฑ€้…็ฝฎ
npm config set registry http://localhost:8081/registry/npm
yarn config set registry http://localhost:8081/registry/npm

๐Ÿ“– API

ไปฃ็†็ซฏ็‚น

่ทฏๅพ„ ๆ–นๆณ• ่ฏดๆ˜Ž
/{full_path:path} GET/HEAD/POST/PUT/DELETE ้€š็”จไปฃ็†ๅ…ฅๅฃ๏ผŒๆ นๆฎ่ทฏ็”ฑ่ง„ๅˆ™่ฝฌๅ‘ๅˆฐๅฏนๅบ”ไธŠๆธธ

็ฎก็†็ซฏ็‚น

่ทฏๅพ„ ๆ–นๆณ• ่ฏดๆ˜Ž ๅ“ๅบ”็คบไพ‹
/health GET ๅฅๅบทๆฃ€ๆŸฅ {"status": "ok", "active_downloads": 0, "downloads": []}
/stats GET ็ผ“ๅญ˜็ปŸ่ฎกไฟกๆฏ {"cache": {"total_size_mb": 1024, "file_count": 100}}

ๅฅๅบทๆฃ€ๆŸฅๅ“ๅบ”่ฏฆๆƒ…

curl http://localhost:8081/health

ๅ“ๅบ”ๅญ—ๆฎต่ฏดๆ˜Ž๏ผš

  • status: ๆœๅŠก็Šถๆ€๏ผŒok ่กจ็คบๆญฃๅธธ่ฟ่กŒ
  • active_downloads: ๅฝ“ๅ‰ๆญฃๅœจ่ฟ›่กŒ็š„ไธ‹่ฝฝไปปๅŠกๆ•ฐ
  • downloads: ๆญฃๅœจไธ‹่ฝฝ็š„ๆ–‡ไปถๅˆ—่กจ๏ผˆ็ผ“ๅญ˜ key๏ผ‰

็ผ“ๅญ˜็ปŸ่ฎกๅ“ๅบ”่ฏฆๆƒ…

curl http://localhost:8081/stats | jq

ๅ“ๅบ”ๅŒ…ๅซ็ผ“ๅญ˜็›ฎๅฝ•็š„ๆ€ปๅคงๅฐใ€ๆ–‡ไปถๆ•ฐ้‡็ญ‰ไฟกๆฏใ€‚

๐Ÿš€ ๅฟซ้€Ÿๅผ€ๅง‹

ๆ–นๅผไธ€๏ผšpip ๅฎ‰่ฃ…๏ผˆๆŽจ่๏ผ‰

# ๅฎ‰่ฃ…
pip install aimirror

# ๅฏๅŠจ
aimirror

# ไฝฟ็”จ
curl http://localhost:8081/health

ๆ–นๅผไบŒ๏ผšๆบ็ ๅฎ‰่ฃ…

# ๅ…‹้š†ไป“ๅบ“
git clone https://github.com/livehl/aimirror.git
cd aimirror

# ๅฎ‰่ฃ…ไพ่ต–
pip install -r requirements.txt

# ๅฏๅŠจ
python main.py

# ไฝฟ็”จ
curl http://localhost:8081/health

๐Ÿณ Docker ้ƒจ็ฝฒ

ไฝฟ็”จ GitHub Container Registry

# ๆ‹‰ๅ–้•œๅƒ
docker pull ghcr.io/livehl/aimirror:latest

# ่ฟ่กŒ๏ผˆๅŸบ็ก€็‰ˆ๏ผ‰
docker run -d -p 8081:8081 \
  -v $(pwd)/cache:/data/fast_proxy/cache \
  ghcr.io/livehl/aimirror:latest

# ่ฟ่กŒ๏ผˆๅธฆ่‡ชๅฎšไน‰้…็ฝฎ๏ผ‰
docker run -d -p 8081:8081 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -v $(pwd)/cache:/data/fast_proxy/cache \
  ghcr.io/livehl/aimirror:latest

Docker Compose ็คบไพ‹

version: '3.8'

services:
  aimirror:
    image: ghcr.io/livehl/aimirror:latest
    container_name: aimirror
    ports:
      - "8081:8081"
    volumes:
      - ./config.yaml:/app/config.yaml
      - ./cache:/data/fast_proxy/cache
      - ./logs:/data/fast_proxy
    restart: unless-stopped

ๆณจๆ„๏ผšไธŠๆธธไปฃ็†่ฏทๅœจ config.yaml ไธญ้…็ฝฎ server.upstream_proxy๏ผŒไธๆ”ฏๆŒ็Žฏๅขƒๅ˜้‡ๆ–นๅผใ€‚

โš™๏ธ ้…็ฝฎ็คบไพ‹

# fast_proxy ้…็ฝฎๆ–‡ไปถ
server:
  host: "0.0.0.0"
  port: 8081
  upstream_proxy: ""  # ไธŠๆธธไปฃ็†๏ผŒ้ป˜่ฎค็ฉบ่กจ็คบ็›ด่ฟž
  public_host: "127.0.0.1:8081"  # ๅฏนๅค–่ฎฟ้—ฎๅœฐๅ€๏ผŒ็”จไบŽ HTML ้“พๆŽฅๆ”นๅ†™
  max_concurrent_downloads: 100  # ๅ…จๅฑ€ๆœ€ๅคงๅนถๅ‘ไธ‹่ฝฝๆ•ฐ๏ผŒ่ถ…่ฟ‡ๅˆ™ๆŽ’้˜Ÿ

cache:
  dir: "/data/fast_proxy/cache"
  max_size_gb: 100
  lru_enabled: true

rules:
  # Docker Registry ไปฃ็†๏ผˆ/v2/ ๅ’Œ /v2/auth ๅœจไปฃ็ ไธญ็‰นๆฎŠๅค„็†๏ผ‰
  - name: docker-blob
    pattern: "/v2/.*/blobs/sha256:[a-f0-9]+"
    upstream: "https://registry-1.docker.io"
    strategy: parallel
    min_size: 1       # all
    concurrency: 20
    chunk_size: 0     # ่‡ชๅŠจๆจกๅผ๏ผšๆ€ปๅคงๅฐ/concurrency๏ผŒ้ฟๅ…่ถ…ๅคงๆ–‡ไปถๅˆ†็‰‡่ฟ‡ๅคšๅฏผ่‡ด token ่ถ…ๆ—ถ
  - name: docker-registry
    pattern: "/v2/.*"
    upstream: "https://registry-1.docker.io"
    strategy: proxy
    handler: handlers.docker  # ็‰นๆฎŠๅค„็†ๆจกๅ—่ทฏๅพ„
    
  - name: pip-packages
    pattern: "/packages/.+\\.(whl|tar\\.gz|zip)$"
    upstream: "https://pypi.org"
    strategy: parallel
    min_size: 1       # all
    concurrency: 20
    chunk_size: 5242880      # 5MB per chunk
    
  - name: r-package
    pattern: "/src/contrib/.*"
    upstream: "https://cran.r-project.org"
    strategy: parallel
    min_size: 102400       # 100K
    concurrency: 20
    chunk_size: 5242880

  - name: huggingface-files
    pattern: '/.*/(blob|resolve)/[^/]+/.+'
    upstream: "https://huggingface.co"
    strategy: parallel
    min_size: 102400       #100k
    concurrency: 20
    chunk_size: 10485760    # 10MB per chunk
    cache_key_source: original  # ไฝฟ็”จๅŽŸๅง‹ URL ไฝœไธบ็ผ“ๅญ˜ key๏ผˆ้ฟๅ…ไธดๆ—ถ็ญพๅๅฝฑๅ“็ผ“ๅญ˜ๅ‘ฝไธญ๏ผ‰
    path_rewrite:
      - search: "/blob/"
        replace: "/resolve/"
    # HEAD ่ฏทๆฑ‚ๆ—ถ้œ€่ฆ้ขๅค–ไฟ็•™็š„ๅ“ๅบ”ๅคด๏ผˆ็”จไบŽๅ…ƒๆ•ฐๆฎ่Žทๅ–๏ผ‰
    head_meta_headers:
      - "x-repo-commit"
      - "x-linked-etag"
      - "x-linked-size"
      - "etag"

  - name: huggingface-api
    pattern: '/api/models/.*'
    upstream: "https://huggingface.co"
    strategy: proxy

  # ็คบไพ‹๏ผšๅ…ถไป–ไฝฟ็”จไธดๆ—ถ็ญพๅ URL ็š„็ซ™็‚น
  # - name: example-signed-url
  #   pattern: '/signed-download/.*'
  #   upstream: "https://example.com"
  #   strategy: parallel
  #   min_size: 10485760
  #   concurrency: 10
  #   cache_key_source: original  # ไฝฟ็”จๅŽŸๅง‹ URL ไฝœไธบ็ผ“ๅญ˜ key

  - name: default
    pattern: ".*"
    upstream: "https://pypi.org"
    strategy: proxy
    content_rewrite:         # ๅ“ๅบ”ๅ†…ๅฎนๆ”นๅ†™้…็ฝฎ
      content_types:         # ๅŒน้…็š„ Content-Type๏ผˆHTML ๅ’Œ JSON๏ผ‰
        - "text/html"
        - "application/json"
        - "application/vnd.pypi.simple"
      targets:               # ่ฆๆ›ฟๆข็š„็›ฎๆ ‡ host ๅˆ—่กจ
        - "https://files.pythonhosted.org"

logging:
  level: "INFO"
  file: "/data/fast_proxy/fast_proxy.log"

้…็ฝฎ่ฏดๆ˜Ž

Server ้…็ฝฎ

ๅญ—ๆฎต ่ฏดๆ˜Ž ้ป˜่ฎคๅ€ผ
server.host ๆœๅŠก็›‘ๅฌๅœฐๅ€ "0.0.0.0"
server.port ๆœๅŠก็›‘ๅฌ็ซฏๅฃ 8081
server.upstream_proxy ไธŠๆธธไปฃ็†ๅœฐๅ€๏ผŒ็ฉบๅญ—็ฌฆไธฒ่กจ็คบ็›ด่ฟž ""
server.public_host ๅฏนๅค–่ฎฟ้—ฎๅœฐๅ€๏ผŒ็”จไบŽ HTML ้“พๆŽฅๆ”นๅ†™ "127.0.0.1:8081"
server.max_concurrent_downloads ๅ…จๅฑ€ๆœ€ๅคงๅนถๅ‘ไธ‹่ฝฝๆ•ฐ๏ผŒ่ถ…่ฟ‡ๅˆ™ๆŽ’้˜Ÿ 100

Cache ้…็ฝฎ

ๅญ—ๆฎต ่ฏดๆ˜Ž ้ป˜่ฎคๅ€ผ
cache.dir ็ผ“ๅญ˜็›ฎๅฝ•่ทฏๅพ„ "./cache"
cache.max_size_gb ็ผ“ๅญ˜ๆœ€ๅคงๅฎน้‡๏ผˆGB๏ผ‰ 100
cache.lru_enabled ๆ˜ฏๅฆๅฏ็”จ LRU ่‡ชๅŠจๆท˜ๆฑฐ true

Rules ้…็ฝฎ

ๅญ—ๆฎต ่ฏดๆ˜Ž ็คบไพ‹
rules[].name ่ง„ๅˆ™ๅ็งฐ "docker-blob"
rules[].pattern URL ๅŒน้…ๆญฃๅˆ™่กจ่พพๅผ "/v2/.*/blobs/sha256:[a-f0-9]+"
rules[].upstream ไธŠๆธธๆบ base URL "https://registry-1.docker.io"
rules[].strategy ไธ‹่ฝฝ็ญ–็•ฅ๏ผšproxy ็›ดๆŽฅไปฃ็† / parallel ๅนถ่กŒไธ‹่ฝฝ "parallel"
rules[].min_size ๆœ€ๅฐๆ–‡ไปถๅคงๅฐ๏ผˆๅญ—่Š‚๏ผ‰๏ผŒๅฐไบŽๆญคๅ€ผไฝฟ็”จไปฃ็† 1048576
rules[].concurrency ๅนถ่กŒไธ‹่ฝฝ็บฟ็จ‹ๆ•ฐ 20
rules[].chunk_size ๆฏไธชๅˆ†็‰‡ๅคงๅฐ๏ผˆๅญ—่Š‚๏ผ‰๏ผŒโ‰ค0 ่กจ็คบ่‡ชๅŠจ่ฎก็ฎ—๏ผˆๆ€ปๅคงๅฐ/concurrency๏ผ‰ 10485760
rules[].cache_key_source ็ผ“ๅญ˜ key ๆฅๆบ๏ผšoriginal ไฝฟ็”จๅŽŸๅง‹URL๏ผŒfinal ไฝฟ็”จๆœ€็ปˆURL "original"
rules[].path_rewrite ่ทฏๅพ„้‡ๅ†™่ง„ๅˆ™ๆ•ฐ็ป„ [{search: "/blob/", replace: "/resolve/"}]
rules[].content_rewrite ๅ“ๅบ”ๅ†…ๅฎนๆ”นๅ†™้…็ฝฎ๏ผˆ็”จไบŽ HTML/JSON ไธญ็š„้“พๆŽฅๆ›ฟๆข๏ผ‰ ่ง default ่ง„ๅˆ™
rules[].handler ็‰นๆฎŠๅค„็†ๆจกๅ—่ทฏๅพ„ "handlers.docker"
rules[].head_meta_headers HEAD ่ฏทๆฑ‚ๆ—ถ้ขๅค–ไฟ็•™็š„ๅ“ๅบ”ๅคดๅˆ—่กจ ["etag", "x-repo-commit"]

Logging ้…็ฝฎ

ๅญ—ๆฎต ่ฏดๆ˜Ž ้ป˜่ฎคๅ€ผ
logging.level ๆ—ฅๅฟ—็บงๅˆซ๏ผšDEBUG/INFO/WARNING/ERROR "INFO"
logging.file ๆ—ฅๅฟ—ๆ–‡ไปถ่ทฏๅพ„ "/tmp/fast_proxy.log"

้ซ˜็บง้…็ฝฎ็คบไพ‹

่‡ชๅฎšไน‰ Handler

ๅˆ›ๅปบ handlers/custom.py๏ผš

async def exec_path(request, full_path, config, http_client):
    """
    ่‡ชๅฎšไน‰่ฏทๆฑ‚ๅค„็†ๅ™จ
    
    Args:
        request: FastAPI Request ๅฏน่ฑก
        full_path: ่ฏทๆฑ‚่ทฏๅพ„
        config: ๅ…จๅฑ€้…็ฝฎๅญ—ๅ…ธ
        http_client: httpx.AsyncClient ๅฎžไพ‹
    
    Returns:
        (handled, response): 
        - handled: bool๏ผŒๆ˜ฏๅฆๅทฒๅค„็†
        - response: ๅฆ‚ๆžœ handled=True๏ผŒ่ฟ”ๅ›ž Response ๅฏน่ฑก
    """
    if full_path.startswith('/custom/'):
        # ๅค„็†่‡ชๅฎšไน‰้€ป่พ‘
        return True, Response(content="Custom response")
    
    # ๆœชๅค„็†๏ผŒ็ปง็ปญๅŽ็ปญๆต็จ‹
    return False, None

ๅœจ config.yaml ไธญ้…็ฝฎ๏ผš

rules:
  - name: custom-handler
    pattern: "/custom/.*"
    upstream: "https://example.com"
    strategy: proxy
    handler: handlers.custom

ๆ‰ฉๅฑ•็คบไพ‹๏ผšๆทปๅŠ  GitHub Releases ไธ‹่ฝฝๅŠ ้€Ÿ

rules:
  - name: github-releases
    pattern: '/.*/releases/download/.+'
    upstream: "https://github.com"
    strategy: parallel
    min_size: 1048576      # 1MB ไปฅไธŠๅฏ็”จๅนถ่กŒ
    concurrency: 16
    chunk_size: 10485760   # 10MB ๅˆ†็‰‡

ๆ‰ฉๅฑ•็คบไพ‹๏ผšๆทปๅŠ ่‡ชๅฎšไน‰่ฝฏไปถๆบ

rules:
  - name: my-company-repo
    pattern: '/artifacts/.+\.(jar|war|zip)$'
    upstream: "https://artifacts.mycompany.com"
    strategy: parallel
    min_size: 10485760     # 10MB ไปฅไธŠๅฏ็”จๅนถ่กŒ
    concurrency: 10
    chunk_size: 20971520   # 20MB ๅˆ†็‰‡
    cache_key_source: original

๐Ÿงช ๆต‹่ฏ•

่ฟ่กŒๆต‹่ฏ•

# ่ฟ่กŒ็ฎ€ๅ•ๆต‹่ฏ•๏ผˆๆ— ้œ€ pytest๏ผ‰
python test_simple.py

# ่ฟ่กŒๅฎŒๆ•ดๆต‹่ฏ•ๅฅ—ไปถ๏ผˆ้œ€่ฆ pytest๏ผ‰
pytest test_proxy.py -v

ๆ‰‹ๅŠจ้ชŒ่ฏ

ๆต‹่ฏ• PyPI ไปฃ็†

curl -o /dev/null "http://localhost:8081/packages/fb/d7/71b982339efc4fff3c622c6fefecddfd3e0b35b60c5f822872d5b806bb71/torch-1.0.0-cp27-cp27m-manylinux1_x86_64.whl" \
  -w "HTTP: %{http_code}, Size: %{size_download}, Time: %{time_total}s\n"

ๆต‹่ฏ• HuggingFace ไปฃ็†

export HF_ENDPOINT=http://localhost:8081

# ๆต‹่ฏ•ไธ‹่ฝฝ GGUF ๆจกๅž‹ๆ–‡ไปถ
huggingface-cli download TheBloke/Llama-2-7B-GGUF llama-2-7b.Q4_K_M.gguf

# ๆต‹่ฏ•ไธ‹่ฝฝ safetensors ๆ ผๅผๆจกๅž‹
huggingface-cli download meta-llama/Llama-2-7b-hf model-00001-of-00002.safetensors

# ๆต‹่ฏ•ไธ‹่ฝฝๆ•ดไธชไป“ๅบ“
huggingface-cli download sentence-transformers/all-MiniLM-L6-v2 --local-dir ./test-model

ๆต‹่ฏ• Docker Registry ไปฃ็†

# ่Žทๅ– token
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/nginx:pull" \
  | grep -o '"token":"[^"]*"' | cut -d'"' -f4)

# ไธ‹่ฝฝ blob
curl -o /dev/null "http://localhost:8081/v2/library/nginx/blobs/sha256:abc123" \
  -H "Authorization: Bearer $TOKEN" \
  -w "HTTP: %{http_code}, Size: %{size_download}, Time: %{time_total}s\n"

้ชŒ่ฏ็ผ“ๅญ˜ๅ‘ฝไธญ

# ็ฌฌไธ€ๆฌกไธ‹่ฝฝ๏ผˆๅนถ่กŒไธ‹่ฝฝ๏ผ‰
time curl -o /tmp/test1.gguf "http://localhost:8081/unsloth/model/resolve/main/file.gguf"

# ็ฌฌไบŒๆฌกไธ‹่ฝฝ๏ผˆ็ผ“ๅญ˜ๅ‘ฝไธญ๏ผŒๅบ”่ฏฅๅฟซๅพˆๅคš๏ผ‰
time curl -o /tmp/test2.gguf "http://localhost:8081/unsloth/model/resolve/main/file.gguf"

# ๆŸฅ็œ‹็ผ“ๅญ˜็ปŸ่ฎก
curl http://localhost:8081/stats | jq

๐Ÿ“„ License

MIT

View on GitHub

Recent activity

commits and pull requests

Recent open issues

view all

Releases and announcements

24 total
  1. v0.3.4v0.3.4Mar 15, 2026

    ๅˆ†ๅ—ๆ–ญ็‚น็ปญไผ 

  2. v0.3.3v0.3.3Mar 15, 2026

    fix

  3. v0.3.2v0.3.2Mar 15, 2026

    chunk_size=0ๆ—ถ็ฆ็”จๅคšไปปๅŠกๅนถๅ‘ไธ‹่ฝฝ๏ผŒ้ฟๅ…็บฟ็จ‹ๆŠขๅ ใ€‚

  4. v0.3.1v0.3.1Mar 14, 2026

    ๆ”ฏๆŒ่ทฏๅพ„้‡ๅ†™๏ผŒๆ”ฏๆŒnvidiaๅ’Œtorch็š„ๅœฐๅ€

  5. v0.3.0v0.3.0Mar 10, 2026

    ไฟฎๅค่ฟžๆŽฅๆฑ ๆณ„้œฒ็š„้—ฎ้ข˜ใ€‚

Commits per week

last 52 weeks
330Week of 2025-08-09: 0 commitsWeek of 2025-08-16: 0 commitsWeek of 2025-08-23: 0 commitsWeek of 2025-08-30: 0 commitsWeek of 2025-09-06: 0 commitsWeek of 2025-09-13: 0 commitsWeek of 2025-09-20: 0 commitsWeek of 2025-09-27: 0 commitsWeek of 2025-10-04: 0 commitsWeek of 2025-10-11: 0 commitsWeek of 2025-10-18: 0 commitsWeek of 2025-10-25: 0 commitsWeek of 2025-11-01: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 0 commitsWeek of 2026-02-08: 0 commitsWeek of 2026-02-15: 0 commitsWeek of 2026-02-22: 0 commitsWeek of 2026-03-01: 33 commitsWeek of 2026-03-08: 9 commitsWeek of 2026-03-15: 9 commitsWeek of 2026-03-22: 0 commitsWeek of 2026-03-29: 0 commitsWeek of 2026-04-05: 0 commitsWeek of 2026-04-12: 0 commitsWeek of 2026-04-19: 0 commitsWeek of 2026-04-26: 0 commitsWeek of 2026-05-03: 0 commitsWeek of 2026-05-10: 0 commitsWeek of 2026-05-17: 0 commitsWeek of 2026-05-24: 0 commitsWeek of 2026-05-31: 0 commitsWeek of 2026-06-07: 0 commitsWeek of 2026-06-14: 0 commitsWeek of 2026-06-21: 0 commitsWeek of 2026-06-28: 0 commitsWeek of 2026-07-05: 0 commitsWeek of 2026-07-12: 0 commitsWeek of 2026-07-19: 0 commitsWeek of 2026-07-26: 0 commitsWeek of 2026-08-02: 0 commitsAug 9, 2025Aug 2, 2026
51 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 โ€” 0 commitsSun 1:00 โ€” 0 commitsSun 2:00 โ€” 0 commitsSun 3:00 โ€” 0 commitsSun 4:00 โ€” 4 commitsSun 5:00 โ€” 0 commitsSun 6:00 โ€” 0 commitsSun 7:00 โ€” 4 commitsSun 8:00 โ€” 1 commitsSun 9:00 โ€” 0 commitsSun 10:00 โ€” 0 commitsSun 11:00 โ€” 0 commitsSun 12:00 โ€” 0 commitsSun 13:00 โ€” 0 commitsSun 14:00 โ€” 0 commitsSun 15:00 โ€” 0 commitsSun 16:00 โ€” 0 commitsSun 17:00 โ€” 0 commitsSun 18:00 โ€” 0 commitsSun 19:00 โ€” 0 commitsSun 20:00 โ€” 0 commitsSun 21:00 โ€” 0 commitsSun 22:00 โ€” 0 commitsSun 23:00 โ€” 0 commitsMon 0:00 โ€” 0 commitsMon 1:00 โ€” 0 commitsMon 2:00 โ€” 0 commitsMon 3:00 โ€” 0 commitsMon 4:00 โ€” 0 commitsMon 5:00 โ€” 0 commitsMon 6:00 โ€” 0 commitsMon 7:00 โ€” 0 commitsMon 8:00 โ€” 0 commitsMon 9:00 โ€” 0 commitsMon 10:00 โ€” 0 commitsMon 11:00 โ€” 0 commitsMon 12:00 โ€” 0 commitsMon 13:00 โ€” 0 commitsMon 14:00 โ€” 0 commitsMon 15:00 โ€” 0 commitsMon 16:00 โ€” 0 commitsMon 17:00 โ€” 0 commitsMon 18:00 โ€” 0 commitsMon 19:00 โ€” 0 commitsMon 20:00 โ€” 0 commitsMon 21:00 โ€” 0 commitsMon 22:00 โ€” 0 commitsMon 23:00 โ€” 0 commitsTue 0:00 โ€” 0 commitsTue 1:00 โ€” 0 commitsTue 2:00 โ€” 3 commitsTue 3:00 โ€” 1 commitsTue 4:00 โ€” 0 commitsTue 5:00 โ€” 0 commitsTue 6:00 โ€” 0 commitsTue 7:00 โ€” 0 commitsTue 8:00 โ€” 0 commitsTue 9:00 โ€” 0 commitsTue 10:00 โ€” 0 commitsTue 11:00 โ€” 0 commitsTue 12:00 โ€” 0 commitsTue 13:00 โ€” 0 commitsTue 14:00 โ€” 0 commitsTue 15:00 โ€” 0 commitsTue 16:00 โ€” 0 commitsTue 17:00 โ€” 0 commitsTue 18:00 โ€” 0 commitsTue 19:00 โ€” 0 commitsTue 20:00 โ€” 0 commitsTue 21:00 โ€” 0 commitsTue 22:00 โ€” 2 commitsTue 23:00 โ€” 0 commitsWed 0:00 โ€” 0 commitsWed 1:00 โ€” 0 commitsWed 2:00 โ€” 0 commitsWed 3:00 โ€” 0 commitsWed 4:00 โ€” 0 commitsWed 5:00 โ€” 0 commitsWed 6:00 โ€” 0 commitsWed 7:00 โ€” 0 commitsWed 8:00 โ€” 0 commitsWed 9:00 โ€” 0 commitsWed 10:00 โ€” 0 commitsWed 11:00 โ€” 0 commitsWed 12:00 โ€” 0 commitsWed 13:00 โ€” 0 commitsWed 14:00 โ€” 0 commitsWed 15:00 โ€” 0 commitsWed 16:00 โ€” 0 commitsWed 17:00 โ€” 0 commitsWed 18:00 โ€” 0 commitsWed 19:00 โ€” 0 commitsWed 20:00 โ€” 0 commitsWed 21:00 โ€” 0 commitsWed 22:00 โ€” 0 commitsWed 23:00 โ€” 0 commitsThu 0:00 โ€” 0 commitsThu 1:00 โ€” 0 commitsThu 2:00 โ€” 0 commitsThu 3:00 โ€” 0 commitsThu 4:00 โ€” 0 commitsThu 5:00 โ€” 0 commitsThu 6:00 โ€” 0 commitsThu 7:00 โ€” 0 commitsThu 8:00 โ€” 0 commitsThu 9:00 โ€” 0 commitsThu 10:00 โ€” 0 commitsThu 11:00 โ€” 0 commitsThu 12:00 โ€” 0 commitsThu 13:00 โ€” 0 commitsThu 14:00 โ€” 1 commitsThu 15:00 โ€” 4 commitsThu 16:00 โ€” 0 commitsThu 17:00 โ€” 0 commitsThu 18:00 โ€” 0 commitsThu 19:00 โ€” 0 commitsThu 20:00 โ€” 0 commitsThu 21:00 โ€” 0 commitsThu 22:00 โ€” 0 commitsThu 23:00 โ€” 0 commitsFri 0:00 โ€” 2 commitsFri 1:00 โ€” 2 commitsFri 2:00 โ€” 2 commitsFri 3:00 โ€” 1 commitsFri 4:00 โ€” 1 commitsFri 5:00 โ€” 1 commitsFri 6:00 โ€” 1 commitsFri 7:00 โ€” 0 commitsFri 8:00 โ€” 0 commitsFri 9:00 โ€” 0 commitsFri 10:00 โ€” 0 commitsFri 11:00 โ€” 0 commitsFri 12:00 โ€” 0 commitsFri 13:00 โ€” 2 commitsFri 14:00 โ€” 1 commitsFri 15:00 โ€” 1 commitsFri 16:00 โ€” 0 commitsFri 17:00 โ€” 0 commitsFri 18:00 โ€” 0 commitsFri 19:00 โ€” 0 commitsFri 20:00 โ€” 0 commitsFri 21:00 โ€” 0 commitsFri 22:00 โ€” 0 commitsFri 23:00 โ€” 3 commitsSat 0:00 โ€” 0 commitsSat 1:00 โ€” 2 commitsSat 2:00 โ€” 1 commitsSat 3:00 โ€” 2 commitsSat 4:00 โ€” 3 commitsSat 5:00 โ€” 0 commitsSat 6:00 โ€” 0 commitsSat 7:00 โ€” 0 commitsSat 8:00 โ€” 1 commitsSat 9:00 โ€” 0 commitsSat 10:00 โ€” 5 commitsSat 11:00 โ€” 0 commitsSat 12:00 โ€” 0 commitsSat 13:00 โ€” 0 commitsSat 14:00 โ€” 0 commitsSat 15:00 โ€” 0 commitsSat 16:00 โ€” 0 commitsSat 17:00 โ€” 0 commitsSat 18:00 โ€” 0 commitsSat 19:00 โ€” 0 commitsSat 20:00 โ€” 0 commitsSat 21:00 โ€” 0 commitsSat 22:00 โ€” 0 commitsSat 23:00 โ€” 0 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.

Who is committing

last 52 weeks
Maintainer commits51 (100%)
Community commits0 (0%)

51 commits in total over the last year.

DateListRankStars gained
Mar 11, 2026daily#18+136
  • public-apis/public-apis

    A collective list of free APIs

    454.9K stars ยท Python

  • donnemartin/system-design-primer

    Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.

    362.2K stars ยท Python

  • practical-tutorials/project-based-learning

    Curated list of project-based tutorials

    277.2K stars ยท Python

  • affaan-m/ECC

    The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

    238.5K stars ยท JavaScript

  • affaan-m/ECC

    The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

    234.7K stars ยท JavaScript

  • NousResearch/hermes-agent

    The agent that grows with you

    227K stars ยท Python