File size: 5,313 Bytes
880dff9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #!/usr/bin/env bash
# 四个 baseline 臂(linear / xattn / prompt / adaln)的单卡端到端 smoke:
# 每臂:单进程 train.py(不走 DeepSpeed)--limit 8 --max_steps 2 → 导出 step-2.safetensors
# → 用该 ckpt 推理一条 right:1.0:21(20 步)并实测位移 → check_ckpt(CPU)strict 装回
# 最后把每臂的 n_new_params / step_time / 峰值显存 / 实测位移汇总到 outputs/smoke_baselines/summary.json。
# 用法:bash scripts/smoke_baselines.sh # 四臂依次在 GPUS(默认 4 5 6 7)上轮流跑
# ARMS="linear adaln" bash scripts/smoke_baselines.sh
# PARALLEL=1 bash scripts/smoke_baselines.sh # 四臂各占一张卡并行(要有四张空闲卡)
# SUMMARY_ONLY=1 bash scripts/smoke_baselines.sh # 只重算汇总(各臂产物已在)
# 单卡无 DeepSpeed 时 AdamW 直接更新 bf16 参数,峰值显存 ≈ 47 GB(权重 + 梯度 + 两份 Adam 状态各 10 GB + 激活)。
set -euo pipefail
ROOT=/opt/dlami/nvme/zhiyangdeng/ActionRoPE
PY=$ROOT/.venv/bin/python
export DIFFSYNTH_SKIP_DOWNLOAD=True
export PYTHONPATH="$ROOT"
ARMS="${ARMS:-linear xattn prompt adaln}"
GPUS=(${GPUS:-4 5 6 7})
PARALLEL="${PARALLEL:-0}"
INFER_STEPS="${INFER_STEPS:-20}"
CLIP="${CLIP:-clip_Eybx_200000958_000273}" # val_eybx,tidal_flats,sidecar valid
OUT=$ROOT/outputs/smoke_baselines
mkdir -p "$OUT" "$ROOT/outputs/samples"
LOG=$OUT/smoke_baselines.log
exec > >(tee -a "$LOG") 2>&1
T_ALL=$(date +%s)
run_arm() { # run_arm <arm> <gpu>
local ARM=$1 GPU=$2 T0 RUN CKPT
T0=$(date +%s)
RUN=$ROOT/outputs/smoke_${ARM}_1gpu
mkdir -p "$RUN"
echo "===== [$ARM] GPU $GPU:单卡 2 步训练 → $RUN ($(date '+%F %T')) ====="
CUDA_VISIBLE_DEVICES=$GPU "$PY" "$ROOT/actionrope/train.py" \
--arm "$ARM" --limit 8 --max_steps 2 --save_every 2 --val_every 0 --warmup_steps 0 \
--num_workers 2 --seed 0 --output "$RUN" 2>&1 | tee "$RUN/train.log"
CKPT=$RUN/step-2.safetensors
test -s "$CKPT"
echo "===== [$ARM] GPU $GPU:step-2 推理 right:1.0:21($INFER_STEPS 步) ====="
CUDA_VISIBLE_DEVICES=$GPU "$PY" -m actionrope.infer --ckpt "$CKPT" --first_frame "$CLIP" --scene tidal_flats \
--actions "right:1.0:21" --steps "$INFER_STEPS" --seed 0 \
--out "$ROOT/outputs/samples/smoke_${ARM}_right_x1.mp4" 2>&1 | tee "$RUN/infer.log"
echo "===== [$ARM]:check_ckpt(CPU,臂按 ckpt 自动识别) ====="
"$PY" "$ROOT/tests/check_ckpt.py" "$CKPT" --json_out "$RUN/check_ckpt.json" > "$RUN/check_ckpt.log" 2>&1
"$PY" -c "import json; r=json.load(open('$RUN/check_ckpt.json')); assert r['strict_load_ok'] and r['arm']=='$ARM', r; print('check_ckpt', {k: r[k] for k in ('arm','n_tensors','n_arm_tensors','n_new_params','n_changed_tensors','arm_nonzero_tensors') if k in r})"
echo "----- [$ARM] 通过,耗时 $(( $(date +%s) - T0 )) s -----"
}
i=0
PIDS=()
[ "${SUMMARY_ONLY:-0}" = 1 ] && ARMS_RUN="" || ARMS_RUN="$ARMS"
for ARM in $ARMS_RUN; do
GPU=${GPUS[$(( i % ${#GPUS[@]} ))]}
if [ "$PARALLEL" = 1 ]; then
run_arm "$ARM" "$GPU" > "$OUT/${ARM}.log" 2>&1 &
PIDS+=($!)
else
run_arm "$ARM" "$GPU"
fi
i=$((i + 1))
done
if [ "$PARALLEL" = 1 ]; then
FAIL=0
for p in "${PIDS[@]}"; do wait "$p" || FAIL=1; done
for ARM in $ARMS; do cat "$OUT/${ARM}.log"; done
[ "$FAIL" = 0 ] || { echo "有臂失败"; exit 1; }
fi
# 汇总:每臂 n_new_params / 2 步的 step_time / 峰值显存 / 推理实测位移
"$PY" - "$OUT/summary.json" $ARMS <<'EOF'
import csv, json, sys
ROOT = "/opt/dlami/nvme/zhiyangdeng/ActionRoPE"
out_path, arms = sys.argv[1], sys.argv[2:]
summary = {}
for arm in arms:
run = f"{ROOT}/outputs/smoke_{arm}_1gpu"
cfg = json.load(open(f"{run}/config.json"))
rows = list(csv.DictReader(open(f"{run}/train_log.csv")))
inf = json.load(open(f"{ROOT}/outputs/samples/smoke_{arm}_right_x1.json"))
chk = json.load(open(f"{run}/check_ckpt.json"))
summary[arm] = {
"n_new_params": cfg["model"]["n_new_params"], "arm_class": cfg["model"]["arm_class"], "arm_kwargs": cfg["model"]["arm_kwargs"],
"text_mode": cfg["args"]["text_mode"], "train_used": cfg["dataset"]["train_used"],
"step_time_s": [round(float(r["step_time"]), 2) for r in rows], "loss": [round(float(r["loss"]), 4) for r in rows],
"grad_norm": [round(float(r["grad_norm"]), 3) for r in rows],
"peak_mem_gb": round(max(float(r["mem_gb"]) for r in rows), 1),
"infer_steps": inf["steps"], "infer_sample_sec": round(inf["sample_sec"], 1), "infer_peak_mem_gb": round(inf["peak_mem_gb"], 1),
"infer_measured_bg_shift_80": inf["measured"]["sift"], "infer_expected_bg_shift_80": inf["expected_bg_shift_80"],
"infer_error_px": inf["error_px"], "infer_sift_source": inf["measured"]["sift_source"],
"ckpt_n_tensors": chk["n_tensors"], "ckpt_n_arm_tensors": chk["n_arm_tensors"],
"ckpt_dit_changed_tensors": chk["n_changed_tensors"], "ckpt_arm_nonzero_tensors": chk.get("arm_nonzero_tensors"),
"ckpt_size_gb": round(chk["size_gb"], 2),
}
json.dump(summary, open(out_path, "w"), indent=2, ensure_ascii=False)
print(json.dumps(summary, indent=1, ensure_ascii=False))
EOF
echo "===== smoke_baselines 全部通过($ARMS),总耗时 $(( $(date +%s) - T_ALL )) s ($(date '+%F %T')) ====="
|