LM Studio切换国内HF-Mirror镜像进行模型下载

LM Studio Hugging Face 本机劫持教程

用本机 TLS 终止代理,把 LM Studio 的 Hugging Face 下载改写到国内镜像 hf-mirror.com,再直连镜像返回的 CDN。目标是:

  • 不走机场 / Clash 节点,不消耗代理流量
  • 绕过 Hugging Face 对境外出口 IP 的风控
  • 绕过 hf-mirror.com 对非国内 IP 的拒绝
  • 兼容 LM Studio 的 useHFProxy(实际首跳是 search.lmstudio.ai,不是 hf-mirror.com

本教程按 Windows 10/11 + LM Studio 0.4.x 实测整理。核心思路与具体域名、路径改写、证书 SAN 都必须按本文落地,缺一项就会继续连官方 Cloudflare。

推荐直接让agent操作


0. 先搞清楚它为什么慢

LM Studio 是 Electron 应用,模型下载走 Node / undici,不是浏览器。

常见误区:

误区 实际情况
开了系统代理,LM Studio 就会走代理 Electron / Node 下载器不读 Windows 系统代理
useHFProxy=true 就会切到 hf-mirror.com 它只是把 URL 改写成 https://search.lmstudio.ai/v1/hf-proxy/<repo>/...
hosts 劫持 huggingface.co 就够了 useHFProxy=true 时首跳是 search.lmstudio.ai
Clash 规则里 DIRECT 就等于宽带直连 Clash 开着时,mihomo 的 DNS / TUN 可能覆盖 hosts
镜像能直接用 Host: huggingface.co 后期镜像会按客户端 IP 检测,非国内 IP 会拒绝或跳回官网

实测过的真实路径:

text 复制代码
LM Studio
  └─ https://search.lmstudio.ai/v1/hf-proxy/<org>/<repo>/resolve/main/<file>
        └─ 本机 127.0.0.1:443 劫持
              ├─ 去掉前缀 /v1/hf-proxy
              ├─ Host 改成 hf-mirror.com
              └─ 用国内出口直连 160.16.86.14:443
                    └─ 302
                          └─ https://us.aws.cdn.hf.co/...
                                └─ 直连可达的 CloudFront 边缘(本文用 13.214.85.108)

因此必须同时劫持:

  • search.lmstudio.ai:LM Studio 内置 HF 中转
  • huggingface.co / hf.co / cdn-lfs.huggingface.co:关闭 useHFProxy 后的直连首跳
  • us.aws.cdn.hf.co:大文件真正落地的 CDN。这一条不要指到 127.0.0.1,要指到一个本机能直连的 CDN IP

1. 前置条件

  1. 宽带本身能直连 hf-mirror.com。hf-mirror会屏蔽非国内IP,先完全退出 Clash / 关闭 TUN 等代理,再访问 hf-mirror.com

如果这里就失败,本方案无效。

  1. 下载期间保持 Clash / TUN 关闭。TUN 的 DNS 劫持会覆盖 hosts
  2. 需要管理员权限:安装本地 CA、改 hosts、监听 443
  3. 需要 Python 3.10+(标准库即可,不用额外包)。
  4. 需要 OpenSSL(Git for Windows 自带即可)。
  5. 本机 IPv6 如果通,必须一起劫持。LM Studio 会优先走 Cloudflare IPv6,只改 IPv4 会被绕过。

先确认镜像 IP 和 CDN IP 仍然可达。这两个地址会变,复刻时不要盲抄:

bash 复制代码
# 查镜像当前 IP
nslookup hf-mirror.com

# 关掉 Clash 后,逐个试 TLS
curl --noproxy "*" -I --resolve hf-mirror.com:443:镜像IP https://hf-mirror.com/

# 查 CDN,再逐个试
nslookup us.aws.cdn.hf.co

本文实测可用的一组:

text 复制代码
hf-mirror.com     -> 160.16.86.14
us.aws.cdn.hf.co  -> 13.214.85.108

如果你测到的可达 IP 不同,后面脚本和 hosts 全部改成你自己的。


2. 目录结构

建议统一放到用户目录,后面所有路径按这个改:

text 复制代码
%USERPROFILE%\hfproxy\
  ca.key
  ca.crt
  server.key
  server.crt
  server.csr
  san.cnf
  hf_hijack.py
  start_lms_hijack.ps1          # 可选:带 DNS 映射启动 LM Studio
  start_proxy_hidden.vbs        # 登录自启

PowerShell:

powershell 复制代码
New-Item -ItemType Directory -Force "$env:USERPROFILE\hfproxy" | Out-Null
cd $env:USERPROFILE\hfproxy

3. 生成本地 CA 和服务器证书

Git Bash 下 openssl -subj /CN=... 会被 MSYS 改成路径,必须先关路径转换。

bash 复制代码
cd "$USERPROFILE/hfproxy"
export MSYS_NO_PATHCONV=1

# 1. 本地 CA
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout ca.key -out ca.crt -days 3650 \
  -subj "/CN=HfHijack Local CA"

# 2. 服务器私钥
openssl genrsa -out server.key 2048

# 3. SAN:必须包含 LM Studio 会访问的所有主机名
cat > san.cnf <<'EOF'
subjectAltName=DNS:huggingface.co,DNS:*.huggingface.co,DNS:cdn-lfs.huggingface.co,DNS:hf.co,DNS:us.aws.cdn.hf.co,DNS:search.lmstudio.ai
EOF

# 4. CSR + 用本地 CA 签发
openssl req -new -key server.key -subj "/CN=huggingface.co" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 3650 -sha256 -extfile san.cnf

# 5. 核对
openssl verify -CAfile ca.crt server.crt
openssl x509 -in server.crt -noout -ext subjectAltName

search.lmstudio.ai 一定要进 SAN。只签 huggingface.co 时,LM Studio 连本机代理会因主机名不匹配直接失败。


4. 把 CA 装进系统,并让 Node 也信任它

Windows 自带 curl / Schannel 认系统根证书;LM Studio 的 Node 下载器默认不读系统根证书。两边都要处理。

管理员 CMD / PowerShell:

bat 复制代码
certutil -addstore -f Root "%USERPROFILE%\hfproxy\ca.crt"

当前用户环境变量(不用管理员):

bat 复制代码
reg add "HKCU\Environment" /v NODE_EXTRA_CA_CERTS /t REG_SZ /d "%USERPROFILE%\hfproxy\ca.crt" /f

立刻对当前会话生效:

powershell 复制代码
$env:NODE_EXTRA_CA_CERTS = "$env:USERPROFILE\hfproxy\ca.crt"

另外清掉失效的本地代理变量。如果以前给 Clash 写过 HTTP_PROXY=http://127.0.0.1:7897,Clash 关掉后 Node 会连死端口然后超时:

bat 复制代码
reg delete "HKCU\Environment" /v HTTP_PROXY /f
reg delete "HKCU\Environment" /v HTTPS_PROXY /f
reg delete "HKCU\Environment" /v ALL_PROXY /f

注意:

  • 新环境变量只对之后启动的进程生效。改完必须彻底退出并重开 LM Studio。
  • Windows curl 是 Schannel 后端,会报 CRYPT_E_NO_REVOCATION_CHECK。这是自签 CA 没有吊销点,不是证书坏了。测试时加 --ssl-no-revoke。LM Studio 的 Node / rustls 不做这项检查

5. 写劫持代理

保存为 %USERPROFILE%\hfproxy\hf_hijack.py。把路径和镜像 IP 改成你自己的。

python 复制代码
# -*- coding: utf-8 -*-
"""
本机 TLS 终止代理:
1. 伪装成 huggingface.co / search.lmstudio.ai
2. 去掉 /v1/hf-proxy 前缀
3. 把 Host 改成 hf-mirror.com
4. 用国内出口直连镜像 IP
"""
import re
import socket
import socketserver
import ssl
import threading
from pathlib import Path

BASE = Path(__file__).resolve().parent
CERT = str(BASE / "server.crt")
KEY = str(BASE / "server.key")

MIRROR_IP = "160.16.86.14"   # 改成你自己测通的 hf-mirror.com IP
MIRROR_HOST = "hf-mirror.com"
LISTEN = ("::", 443)         # IPv6 双栈,同时收 127.0.0.1 和 ::1

server_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
server_ctx.load_cert_chain(CERT, KEY)
server_ctx.set_alpn_protocols(["http/1.1"])  # 强制 HTTP/1.1,方便改 Host

upstream_ctx = ssl.create_default_context()

_HOST_RE = re.compile(rb"^(Host:\s*)([^\r\n]*)", re.MULTILINE)
_REQUEST_RE = re.compile(rb"^([A-Z]+\s+)/v1/hf-proxy/", re.MULTILINE)


def rewrite_request(head: bytes) -> bytes:
    # LM Studio: GET /v1/hf-proxy/org/repo/...  ->  GET /org/repo/...
    head = _REQUEST_RE.sub(rb"\1/", head, count=1)

    def repl(m):
        host = m.group(2).decode("ascii", "ignore").strip()
        if host and host != MIRROR_HOST:
            return m.group(1) + MIRROR_HOST.encode()
        return m.group(0)

    return _HOST_RE.sub(repl, head)


def relay(src, dst):
    try:
        while True:
            data = src.recv(65536)
            if not data:
                break
            dst.sendall(data)
    except Exception:
        pass
    finally:
        for s in (src, dst):
            try:
                s.shutdown(socket.SHUT_RDWR)
            except Exception:
                pass
            try:
                s.close()
            except Exception:
                pass


class Handler(socketserver.BaseRequestHandler):
    def handle(self):
        client = self.request
        try:
            buf = b""
            while b"\r\n\r\n" not in buf:
                chunk = client.recv(4096)
                if not chunk:
                    return
                buf += chunk
                if len(buf) > 100 * 1024:
                    return
            head, rest = buf.split(b"\r\n\r\n", 1)
            head = rewrite_request(head)
            raw = socket.create_connection((MIRROR_IP, 443), timeout=15)
            upstream = upstream_ctx.wrap_socket(raw, server_hostname=MIRROR_HOST)
            upstream.sendall(head + b"\r\n\r\n" + rest)
            t = threading.Thread(target=relay, args=(client, upstream), daemon=True)
            t.start()
            relay(upstream, client)
            t.join(timeout=2)
        except Exception as e:
            print(f"[ERR] {e}", flush=True)


class Server(socketserver.ThreadingTCPServer):
    address_family = socket.AF_INET6
    daemon_threads = True
    allow_reuse_address = True

    def server_bind(self):
        # Windows 默认 V6ONLY=0 也能双栈;显式关掉更稳
        self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
        super().server_bind()


if __name__ == "__main__":
    srv = Server(LISTEN, Handler)
    srv.socket = server_ctx.wrap_socket(srv.socket, server_side=True)
    print(f"HF hijack proxy listening on {LISTEN[0]}:{LISTEN[1]}", flush=True)
    srv.serve_forever()

先手动跑一次,确认没有报错:

bash 复制代码
python "%USERPROFILE%\hfproxy\hf_hijack.py"

应看到:

text 复制代码
HF hijack proxy listening on :::443

另开一个终端看监听:

text 复制代码
0.0.0.0:443    LISTENING
[::]:443       LISTENING

如果 443 被占用,先查是谁:

bat 复制代码
netstat -ano | findstr ":443"

常见占用:IIS、旧代理实例、某些加速器。本方案必须占本机 443,因为客户端访问的是标准 HTTPS 端口。


6. 改 hosts

管理员记事本打开:

text 复制代码
C:\Windows\System32\drivers\etc\hosts

先备份,再追加。us.aws.cdn.hf.co 改成你测通的 CDN IP:

text 复制代码
# === HF hijack ===
127.0.0.1 huggingface.co
127.0.0.1 hf.co
127.0.0.1 cdn-lfs.huggingface.co
127.0.0.1 search.lmstudio.ai
13.214.85.108 us.aws.cdn.hf.co
::1 huggingface.co
::1 hf.co
::1 cdn-lfs.huggingface.co
::1 search.lmstudio.ai
# === end HF hijack ===

然后:

bat 复制代码
ipconfig /flushdns

ping 验证,不要用 nslookupnslookup 绕过 hosts,会显示真实 DNS。

bat 复制代码
ping huggingface.co
ping search.lmstudio.ai
ping us.aws.cdn.hf.co

期望:

text 复制代码
huggingface.co     -> 127.0.0.1
search.lmstudio.ai -> 127.0.0.1
us.aws.cdn.hf.co   -> 13.214.85.108   (或你自己的可达 IP)

::1 那四条不能省。只写 IPv4 时,LM Studio 会直接连 Cloudflare IPv6。


7. 验证代理本身

Clash 必须处于退出状态。Git Bash / PowerShell 都可以。

bash 复制代码
# 1. 元数据:应 200
curl --ssl-no-revoke --noproxy "*" -s -m 20 -o /dev/null -w "HTTP %{http_code}\n" \
  "https://huggingface.co/gpt2/resolve/main/config.json"

# 2. LM Studio 真实 URL 形态:应 302 后能续传
curl --ssl-no-revoke --noproxy "*" -s -m 60 -L \
  -H "Range: bytes=0-8388607" -o /dev/null \
  -w "HTTP %{http_code} speed=%{speed_download}\n" \
  "https://search.lmstudio.ai/v1/hf-proxy/gpt2/resolve/main/pytorch_model.bin"

正常结果:

  • 第一条:HTTP 200
  • 第二条:HTTP 206,速度大约数 MB/s,而不是 100 KB/s

如果是 HTTP 000 / exit 35:代理没起来,或证书 SAN 不对。 如果是 exit 60:CA 没进系统根证书,或 curl 走了 Schannel 且你没加 --ssl-no-revoke。 如果一直连 Cloudflare IP:hosts 没生效,或 Clash TUN 还开着。

再用 LM Studio 自带 Node 测一次,这才接近真实下载栈:

powershell 复制代码
$env:NODE_EXTRA_CA_CERTS = "$env:USERPROFILE\hfproxy\ca.crt"
Remove-Item Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:ALL_PROXY -ErrorAction SilentlyContinue
& "$env:USERPROFILE\.lmstudio\.internal\utils\node.exe" -e @"
const https = require('https');
const url = 'https://search.lmstudio.ai/v1/hf-proxy/gpt2/resolve/main/pytorch_model.bin';
const headers = { Range: 'bytes=0-8388607' };
const t0 = Date.now();
function go(u, n=0) {
  https.get(u, { headers }, res => {
    if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location && n < 5) {
      console.log('redirect', res.statusCode, new URL(res.headers.location).hostname);
      res.resume();
      return go(res.headers.location, n+1);
    }
    let b = 0;
    res.on('data', c => b += c.length);
    res.on('end', () => {
      const s = (Date.now()-t0)/1000;
      console.log('HTTP', res.statusCode, 'bytes='+b, 'MB/s='+(b/s/1048576).toFixed(2));
    });
  }).on('error', e => { console.error(e); process.exit(1); });
}
go(url);
"@

期望输出类似:

text 复制代码
redirect 302 us.aws.cdn.hf.co
HTTP 206 bytes=8388608 MB/s=3.50

8. 配置 LM Studio

8.1 设置

%USERPROFILE%\.lmstudio\settings.json

json 复制代码
"useHFProxy": false

说明:

  • true:首跳变成 search.lmstudio.ai/v1/hf-proxy/...
  • false:首跳是 huggingface.co/...

本代理两种都接。更稳妥是关 useHFProxy,同时继续劫持 search.lmstudio.ai,防止应用把旧任务 URL 改回去。

8.2 旧下载任务

已开始的任务会把 URL 写进:

text 复制代码
%USERPROFILE%\.lmstudio\.internal\download-jobs-info.json

里面可能同时存在:

text 复制代码
request.url  = https://huggingface.co/...
download.url = https://search.lmstudio.ai/v1/hf-proxy/...

LM Studio 恢复任务时可能把 download.url 再写回中转地址。所以不要只改 JSON ,代理必须能处理 /v1/hf-proxy

改配置前先彻底退出 LM Studio,并备份这两个文件。

8.3 启动方式

普通双击也可以,前提是:

  1. 代理已在听 443
  2. hosts 已生效
  3. NODE_EXTRA_CA_CERTS 已写入用户环境
  4. 没有失效的 HTTP_PROXY

可选:用 Chromium 主机映射再兜一层。它对 Chromium Network Service 有效,对主进程 Node fetch() 不保证有效,所以不能代替 hosts

start_lms_hijack.ps1

powershell 复制代码
$rules = 'MAP search.lmstudio.ai 127.0.0.1, MAP huggingface.co 127.0.0.1, MAP hf.co 127.0.0.1, MAP cdn-lfs.huggingface.co 127.0.0.1, MAP us.aws.cdn.hf.co 13.214.85.108, EXCLUDE localhost'

Get-Process -Name 'LM Studio' -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep -Seconds 2

$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = 'D:\AI\LLM\LM Studio\LM Studio.exe'   # 改成你的安装路径
$startInfo.UseShellExecute = $false
$startInfo.Arguments = '--host-resolver-rules="' + $rules + '" --disable-features=UseDnsHttpsSvcbAlpn,AsyncDns'
$startInfo.EnvironmentVariables['NODE_EXTRA_CA_CERTS'] = "$env:USERPROFILE\hfproxy\ca.crt"
$startInfo.EnvironmentVariables.Remove('HTTP_PROXY')
$startInfo.EnvironmentVariables.Remove('HTTPS_PROXY')
$startInfo.EnvironmentVariables.Remove('ALL_PROXY')
[System.Diagnostics.Process]::Start($startInfo) | Out-Null

9. 登录自启代理

把下面内容存成:

text 复制代码
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\HF Mirror Hijack Proxy.vbs

pythonw.exe 用绝对路径,避免登录 PATH 顺序变化:

vb 复制代码
Set shell = CreateObject("WScript.Shell")
shell.Run """C:\Path\To\pythonw.exe"" ""%USERPROFILE%\hfproxy\hf_hijack.py""", 0, False

VBS 里 %USERPROFILE% 不会自动展开,写成真实绝对路径,例如:

vb 复制代码
Set shell = CreateObject("WScript.Shell")
shell.Run """G:\application\scoop\apps\python313\current\pythonw.exe"" ""C:\Users\你的用户名\hfproxy\hf_hijack.py""", 0, False

重启后用 netstat -ano | findstr ":443" 确认还在监听。


10. 怎样判断已经走通

下载开始后看三件事。

1. 连接目标

PowerShell:

powershell 复制代码
Get-NetTCPConnection -State Established |
  Where-Object { (Get-Process -Id $_.OwningProcess -EA SilentlyContinue).ProcessName -eq 'LM Studio' } |
  Select-Object OwningProcess, LocalAddress, RemoteAddress, RemotePort

成功时应该看到:

  • 127.0.0.1:443[::1]:443(首跳进了本机代理)
  • 以及 / 或者 13.214.85.108:443(大文件直连 CDN)

失败时会看到 Cloudflare:

text 复制代码
172.67.x.x
104.26.x.x
2606:4700:...

2. 速度

走通后通常是数 MB/s 到十几 MB/s。还是 100 KB/s 左右,基本还在打官方 Cloudflare。

3. 日志

text 复制代码
%APPDATA%\LM Studio\logs\main.log

证书失败会立刻报错。如果已经下到百分之几再 Timed-out,多半是中转链路慢或本地代理环境变量指向了死端口,不是 CA 问题。


11. 卸载 / 回滚

  1. 退出 LM Studio。
  2. 结束 python / pythonw 里的 hf_hijack.py
  3. 删掉 hosts# === HF hijack === 整段。
  4. ipconfig /flushdns
  5. 删除启动文件夹里的 HF Mirror Hijack Proxy.vbs
  6. 可选:从"受信任的根证书颁发机构"删除 HfHijack Local CA
  7. 可选:删除用户环境变量 NODE_EXTRA_CA_CERTS
  8. useHFProxy 改回你原来的值。

hosts 备份一般在改之前手动复制一份即可。


12. 复刻时最容易踩的坑

  1. 只劫持了 huggingface.co

    LM Studio 开着 useHFProxy 时,真实首跳是 search.lmstudio.ai

  2. 只改了 IPv4 hosts

    LM Studio 会走 2606:4700:... 的 Cloudflare IPv6。

  3. Clash / TUN 还开着。

    TUN DNS 会盖掉 hosts,看起来"映射无效"。

  4. us.aws.cdn.hf.co 也指到 127.0.0.1

    CDN 证书对不上,而且大文件没必要再进本地代理。应指到一个本机能直连的 CDN IP。

  5. 证书 SAN 漏了 search.lmstudio.ai

    握手阶段就会被 Node 拒掉。

  6. 只把 CA 装进了 Windows 根证书库。

    LM Studio 的 Node 还要 NODE_EXTRA_CA_CERTS,并且必须重启应用。

  7. 残留 HTTP_PROXY=http://127.0.0.1:7897

    Clash 关了之后,Node 会连死端口,日志里全是 Timed-out

  8. 镜像 IP / CDN IP 过期。

    160.16.86.1413.214.85.108 只是当时测通的值。复刻当天要重测。

  9. 在境外网络上用这个方案。

    hf-mirror.com 会检测客户端 IP,非国内出口会被拒绝。本方案依赖"本机宽带是国内 IP"。

  10. nslookup 验证 hosts

    它不走 hosts。用 ping 或 PowerShell [System.Net.Dns]::GetHostAddresses('huggingface.co')


13. 最小检查清单

按顺序勾:

  • Clash / TUN 已完全退出
  • 宽带能直连 hf-mirror.com
  • 已确认当前可用的镜像 IP、CDN IP
  • 已生成 CA + 带完整 SAN 的服务器证书
  • CA 已进系统根证书
  • 已设置 NODE_EXTRA_CA_CERTS
  • 已删除失效的 HTTP_PROXY / HTTPS_PROXY / ALL_PROXY
  • hf_hijack.py 正在监听 0.0.0.0:443[::]:443
  • hosts 含 IPv4 + IPv6,且 search.lmstudio.ai 指向本机
  • us.aws.cdn.hf.co 指向可达 CDN IP,而不是 127.0.0.1
  • curl / Node 探测已拿到 200/206 和数 MB/s
  • 已彻底重启 LM Studio
  • 下载进程连的是 127.0.0.1 或 CDN IP,不是 2606:4700 / 172.67

全部勾完后,再在 LM Studio 里点下载。

相关推荐
m4Rk_4 小时前
【论文阅读】Agent 记忆机制(38):AMA——用多智能体协作动态选择记忆粒度
论文阅读·人工智能·学习
青春不败 177-3266-05204 小时前
基于R、Python的Copula变量相关性分析及AI大模型应用
人工智能·python·r语言·贝叶斯·统计学·copula
wx_xkq12884 小时前
2026企业级AI Agent落地观察:从工具集到组织级智能体
大数据·人工智能·saas·ai营销
AI_AGENT_DEV_AI4 小时前
AI 英语口语 APP的开发
人工智能
熊猫_豆豆4 小时前
WOKWI 仿真 ESP32S3 SSD1306 播放GIF图
人工智能·esp32s3·硬件开发·ssd1306
玫瑰互动GEO4 小时前
2026豆包AI搜索GEO优化:从豆包大模型到字节生态信源引用
大数据·人工智能·豆包·geo优化
dozenyaoyida5 小时前
AI与大模型新闻日报 | 2026-08-13
人工智能·ai·大模型·新闻
梦想的旅途25 小时前
企微 API 二次开发:结合 AI 提取聊天记录并智能生成会议纪要
人工智能
陆枫Larry5 小时前
从游戏显卡到 AI 心脏:英伟达三十年简史
人工智能