#!/usr/bin/env bash # 下载 Qwen3-VL-4B-Instruct-4bit(MLX 4bit)全量文件到本地镜像目录,并逐个校验字节数。 # 字节数权威来源:康康/AI/ModelManifest.swift(HF API blobs=true,2026-05 核对)。 # 用法: bash scripts/fetch-qwen3vl.sh set -uo pipefail REPO="mlx-community/Qwen3-VL-4B-Instruct-4bit" BASE="https://huggingface.co/${REPO}/resolve/main" # 目标 = 康康仓库内的 Models/(已被 .gitignore 忽略,App 旁路导入也认这个目录名)。 # 可用环境变量 KK_MODELS_DIR 覆盖根目录(如指向另一块盘)。 ROOT="${KK_MODELS_DIR:-/Users/xuhuayong/apps/康康/Models}" DEST="$ROOT/Qwen3-VL-4B-Instruct-4bit" mkdir -p "$DEST" # 文件名:期望字节数(与 ModelManifest.swift 的 .vl 清单一一对应) FILES=( "config.json:7137" "model.safetensors:3093767283" "model.safetensors.index.json:64742" "tokenizer.json:11422654" "tokenizer_config.json:5445" "vocab.json:2776833" "merges.txt:1671853" "special_tokens_map.json:613" "added_tokens.json:707" "generation_config.json:269" "chat_template.json:5502" "chat_template.jinja:5292" "preprocessor_config.json:782" "video_preprocessor_config.json:817" ) fsize() { stat -f%z "$1" 2>/dev/null || echo 0; } fail=0 for entry in "${FILES[@]}"; do name="${entry%%:*}"; want="${entry##*:}"; out="$DEST/$name" if [[ -f "$out" && "$(fsize "$out")" == "$want" ]]; then echo "SKIP $name (已完整 $want)"; continue fi echo "GET $name (期望 $want 字节)" curl -fL -C - --retry 5 --retry-delay 3 --connect-timeout 30 \ -o "$out" "$BASE/$name" || { echo " !! 下载失败 $name"; fail=1; continue; } have="$(fsize "$out")" if [[ "$have" != "$want" ]]; then echo " !! 字节不符 $name: 实得 $have / 期望 $want"; fail=1 else echo " OK $name $have" fi done # 大权重额外做 SHA256 校验(HF LFS oid,密码学级,字节数相同也能查出脏数据)。 WEIGHT_SHA="90eeb02604181dbcccd0a30a1f550a4a8928ca7dcbee4aee1449239306cfdfca" if [[ -f "$DEST/model.safetensors" ]]; then echo "校验 model.safetensors SHA256(约需 10 余秒)..." got="$(shasum -a 256 "$DEST/model.safetensors" | awk '{print $1}')" if [[ "$got" == "$WEIGHT_SHA" ]]; then echo " ✓ SHA256 匹配" else echo " !! SHA256 不符: 实得 $got / 期望 $WEIGHT_SHA"; fail=1 fi fi echo "================================================" total=$(du -sh "$DEST" 2>/dev/null | cut -f1) echo "目录: $DEST (合计 $total)" if [[ "$fail" == "0" ]]; then echo "✅ 全部 14 个文件下载并校验通过(权重含 SHA256)"; else echo "❌ 有文件失败,重跑本脚本可断点续传"; fi exit "$fail"