首次提交
This commit is contained in:
84
scripts/pack.sh
Normal file
84
scripts/pack.sh
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# 离线部署打包脚本(在【能联网】的机器上跑)
|
||||
#
|
||||
# 两种模式自动识别:
|
||||
# A) 自包含模式(已跑过 make_portable.sh,项目内有 ./python + ./models)
|
||||
# → 打包里只含项目这一个文件夹,离线机解压到【任意路径/任意用户】即可。
|
||||
# B) venv 模式(只有 .venv)
|
||||
# → 打项目 + /root 下的 uv Python + HF 缓存,离线机要解压到相同路径。
|
||||
#
|
||||
# 用法: bash pack.sh
|
||||
# 产物: /tmp/ocr_offline_bundle.tar.gz
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PROJECT_DIR="$(pwd)"
|
||||
OUT="${1:-/tmp/ocr_offline_bundle.tar.gz}"
|
||||
|
||||
log() { echo -e "\n\033[1;32m==> $*\033[0m"; }
|
||||
warn() { echo -e "\033[1;33m[警告] $*\033[0m"; }
|
||||
have() { command -v "$1" >/dev/null 2>&1; }
|
||||
|
||||
PBASE="$(basename "$PROJECT_DIR")"
|
||||
PPARENT="$(dirname "$PROJECT_DIR")"
|
||||
|
||||
# 运行时数据排除(部署不需要,打进去又慢又大)。用项目目录名作前缀,两种模式通用。
|
||||
RT_DIRS=(split video composite coscli_output srt info info_error log)
|
||||
EXCLUDES=(--exclude='*.log' --exclude='__pycache__' --exclude='*.pyc'
|
||||
--exclude="$PBASE/数据.jsonl")
|
||||
for d in "${RT_DIRS[@]}"; do EXCLUDES+=(--exclude="$PBASE/$d"); done
|
||||
|
||||
# 选最快的压缩器:pigz 多线程(输出仍是标准 gzip,离线机普通 tar xzf 就能解)
|
||||
if have pigz; then
|
||||
COMPRESS="pigz"; log "用 pigz 多线程压缩(快)"
|
||||
else
|
||||
COMPRESS="gzip -1"; warn "未装 pigz,用 gzip -1;想更快可先 yum install -y pigz"
|
||||
fi
|
||||
|
||||
if [ -x "$PROJECT_DIR/python/bin/python3" ]; then
|
||||
# ---------- A) 自包含:只打项目目录(用相对名),可解压到任意路径 ----------
|
||||
log "自包含模式(项目内含 ./python + ./models)"
|
||||
[ -d "$PROJECT_DIR/models" ] || warn "没看到 ./models,确认 make_portable.sh 跑完整了"
|
||||
tar "${EXCLUDES[@]}" --use-compress-program="$COMPRESS" -cf "$OUT" \
|
||||
-C "$PPARENT" "$PBASE"
|
||||
MODE="自包含(解压到任意路径/用户)"
|
||||
else
|
||||
# ---------- B) venv:打项目(绝对路径) + 外部 Python + HF 缓存 ----------
|
||||
[ -d .venv ] || { echo "既没有 ./python 也没有 .venv,请先 setup_server.sh 或 make_portable.sh"; exit 1; }
|
||||
# shellcheck disable=SC1091
|
||||
source .venv/bin/activate
|
||||
|
||||
log "venv 模式:确保 headless opencv + 预下载模型"
|
||||
uv pip uninstall opencv-python 2>/dev/null || true
|
||||
uv pip install opencv-python-headless \
|
||||
--index-url "${PIP_MIRROR:-https://repo.huaweicloud.com/repository/pypi/simple}" 2>/dev/null \
|
||||
|| echo "(headless 可能已装,忽略)"
|
||||
MODEL="$(python -c "import json;print(json.load(open('config/config.json'))['audio'].get('model_size','small'))")"
|
||||
HF_HUB_OFFLINE=0 TRANSFORMERS_OFFLINE=0 HF_ENDPOINT="${HF_ENDPOINT:-https://hf-mirror.com}" \
|
||||
python -c "from faster_whisper import WhisperModel; WhisperModel('$MODEL',device='cpu',compute_type='int8'); print('模型已缓存')"
|
||||
|
||||
PYDIR="$(dirname "$(dirname "$(readlink -f .venv/bin/python)")")"
|
||||
HFCACHE="${HF_HOME:-$HOME/.cache/huggingface}"
|
||||
echo " uv Python: $PYDIR 模型缓存: $HFCACHE"
|
||||
|
||||
log "打包项目(绝对路径) + Python + 模型缓存"
|
||||
# 项目用绝对路径(还原到原位),外部两目录同理
|
||||
EXABS=(--exclude='*.log' --exclude='__pycache__' --exclude='*.pyc'
|
||||
--exclude="${PROJECT_DIR#/}/数据.jsonl")
|
||||
for d in "${RT_DIRS[@]}"; do EXABS+=(--exclude="${PROJECT_DIR#/}/$d"); done
|
||||
tar "${EXABS[@]}" --use-compress-program="$COMPRESS" -cf "$OUT" \
|
||||
-C / "${PROJECT_DIR#/}" -C / "${PYDIR#/}" -C / "${HFCACHE#/}"
|
||||
MODE="venv(离线机需解压到相同路径/用户)"
|
||||
fi
|
||||
|
||||
echo
|
||||
log "完成 ✅ $OUT ($(du -h "$OUT" | cut -f1))"
|
||||
echo "模式: $MODE"
|
||||
cat <<EOF
|
||||
|
||||
下一步:
|
||||
scp $OUT root@离线机:/tmp/
|
||||
bash deploy.sh /tmp/$(basename "$OUT") # 自包含模式可加目标路径: bash deploy.sh 包 /opt
|
||||
EOF
|
||||
Reference in New Issue
Block a user