lnp_ml/scripts_run/run_cv5_sample.sh
2026-08-14 16:59:58 +00:00

111 lines
3.6 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# 样本级切分StratifiedKFold下 baseline vs MoE+LLM 对比实验。
# 串行跑两个分支24GB 单卡装不下两个 7B。SSH 断连、GPU 抢占、OOM
# 都靠 --resume-dir 的折级断点续跑恢复,已完成的折不会重算。
set -u
GPU=${GPU:-0}
SEED=${SEED:-42}
ROOT=${ROOT:-models/cv5_sample}
FIX_HP=${FIX_HP:-models/final/best_params.json}
FIX_EM=${FIX_EM:-11}
BATCH=${BATCH:-8}
N_OUTER=${N_OUTER:-5}
N_INNER=${N_INNER:-3}
MIN_FREE_MB=${MIN_FREE_MB:-12000} # 显存不够就等,不硬上
WAIT_STEP=${WAIT_STEP:-60}
MAX_RETRY=${MAX_RETRY:-30}
RETRY_WAIT=${RETRY_WAIT:-120}
MIN_OK_SEC=${MIN_OK_SEC:-120} # 存活不足这么久且无进度 -> 判为配置错误,停止重试
mkdir -p "${ROOT}"
LOG="${ROOT}/run_seed${SEED}.log"
log() { echo "[$(date '+%F %T')] $*" >>"${LOG}"; }
done_folds() { # $1 = 分支目录
ls "$1"/outer_fold_*/test_metrics.json 2>/dev/null | wc -l
}
wait_free() {
while :; do
local free
free=$(nvidia-smi --id="${GPU}" --query-gpu=memory.free \
--format=csv,noheader,nounits 2>/dev/null || echo 0)
[ "${free}" -ge "${MIN_FREE_MB}" ] && break
log "GPU${GPU} 空闲 ${free}MiB < ${MIN_FREE_MB}MiB${WAIT_STEP}s 后重试"
sleep "${WAIT_STEP}"
done
}
# $1 = 分支名,其余参数为该分支特有的 CLI 开关
run_variant() {
local name=$1; shift
local dir="${ROOT}/${name}/seed${SEED}"
mkdir -p "${dir}"
local before after rc dt
before=$(done_folds "${dir}")
if [ "${before}" -ge "${N_OUTER}" ]; then
log "${name}: ${before}/${N_OUTER} 折已完成,整个分支跳过"
return 0
fi
local attempt
for attempt in $(seq 1 "${MAX_RETRY}"); do
wait_free
before=$(done_folds "${dir}")
log "${name} ATTEMPT ${attempt}/${MAX_RETRY}(已完成 ${before}/${N_OUTER} 折)"
local t0=${SECONDS}
CUDA_VISIBLE_DEVICES=${GPU} TRANSFORMERS_OFFLINE=1 TOKENIZERS_PARALLELISM=false \
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
python -u -m lnp_ml.modeling.nested_cv_optuna \
--input-path data/interim/internal.csv \
--output-dir "${ROOT}" \
--resume-dir "${dir}" \
--seed "${SEED}" \
--use-mpnn \
--fix-hparams-json "${FIX_HP}" \
--fix-epoch-mean "${FIX_EM}" \
--n-outer-folds "${N_OUTER}" --n-inner-folds "${N_INNER}" \
--batch-size "${BATCH}" --device cuda \
${@+"$@"} >>"${LOG}" 2>&1
rc=$?
dt=$((SECONDS - t0))
if [ ${rc} -eq 0 ]; then
log "${name} DONE本次用时 ${dt}s$(done_folds "${dir}")/${N_OUTER} 折)"
return 0
fi
after=$(done_folds "${dir}")
if [ ${dt} -lt ${MIN_OK_SEC} ] && [ "${after}" -le "${before}" ]; then
log "${name} 仅存活 ${dt}s 且无进度rc=${rc}),判为配置/代码错误而非抢占,停止重试"
log "${name} 请查看本日志末尾的 traceback"
return ${rc}
fi
log "${name} 运行 ${dt}s 后以 ${rc} 退出(进度 ${before}->${after}${RETRY_WAIT}s 后续跑"
sleep "${RETRY_WAIT}"
done
log "${name} 重试 ${MAX_RETRY} 次仍未完成,放弃"
return 1
}
log "===== 开始:样本级切分对比实验 seed=${SEED} gpu=${GPU} ====="
run_variant baseline || { log "baseline 失败,不再继续 moe_llm"; exit 1; }
run_variant moe_llm \
--use-moe --moe-n-experts 4 --moe-top-k 2 \
--reg-bypass off \
--use-llm --use-rag --rag-top-k 4 \
--use-soft-prompt --llm-use-qlora \
--llm-model-path models/qwen2.5-7b-instruct \
--no-llm-freeze \
--llm-max-length 1536 \
|| { log "moe_llm 失败"; exit 1; }
log "===== 全部完成,两个分支各 ${N_OUTER} 折 ====="