File size: 5,106 Bytes
eafbe80 | 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #!/bin/bash
# Basic capability(可选):单条 GT 轨迹 replay。质量评测主路径见 static 中 long_horizon_gt_replay(多 chunk)。
# 默认 NUM_CHUNKS 与 NUM_CHUNKS_LONG(默认 3)对齐;单 chunk 不足以表征跨 chunk 记忆/误差累积。
# 与 eval_v2 static 对齐:PYTHONPATH、ctx、CAMERA_INJECT_MODE、MEM_ARGS。
# VIDEO_NAME:
# - 显式设置时,要求该 video 在 DATASET/jsons 下有可用 GT pose(按 START_FRAME/NUM_CHUNKS/CHUNK_FRAMES 检查)
# - 未设置时(或 VIDEO_NAME=AUTO),优先 AncientTempleEnv_0;不可用则自动回退到首个可用 video
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
EVAL_DIR="${SCRIPT_DIR}"
REPO_ROOT="$(cd "${EVAL_DIR}/../.." && pwd)"
ENV_DIR="${REPO_ROOT}/env"
# shellcheck disable=SC1091
[ -f "${REPO_ROOT}/env/eval_infer_alignment_env.sh" ] && source "${REPO_ROOT}/env/eval_infer_alignment_env.sh"
cd "${REPO_ROOT}" || exit 1
export PYTHONPATH="${REPO_ROOT}:${PYTHONPATH:-}"
CKPT="${CKPT:?Set CKPT=/path/to/epoch-0.safetensors}"
CKPT_DIR="$(dirname "${CKPT}")"
DATASET="/threed-code/yorenchen/data/echo-memory/Context-as-Memory-Dataset/"
# --- Early path sanity (before any heavy Python) ---
if [ ! -d "${DATASET}" ]; then
echo "[replay_gt] ERROR: DATASET 不是目录: ${DATASET}" >&2
exit 1
fi
if [ ! -d "${DATASET}/jsons" ]; then
echo "[replay_gt] ERROR: 缺少 DATASET/jsons: ${DATASET}/jsons" >&2
exit 1
fi
echo "[replay_gt] DATASET=$(cd "${DATASET}" && pwd)"
VIDEO_NAME="${VIDEO_NAME:-AUTO}"
START_FRAME="${START_FRAME:-0}"
NUM_CHUNKS="${NUM_CHUNKS:-${NUM_CHUNKS_LONG:-3}}"
CHUNK_FRAMES_EFFECTIVE="${CHUNK_FRAMES:-81}"
_resolve_video_name() {
local wanted="$1"
DATASET="${DATASET}" \
EVAL_DIR="${EVAL_DIR}" \
VIDEO_NAME_IN="${wanted}" \
START_FRAME="${START_FRAME}" \
NUM_CHUNKS="${NUM_CHUNKS}" \
CHUNK_FRAMES="${CHUNK_FRAMES_EFFECTIVE}" \
python3 - <<'PY'
import os
import sys
dataset = os.environ["DATASET"]
eval_dir = os.environ["EVAL_DIR"]
wanted = os.environ.get("VIDEO_NAME_IN", "").strip()
start = int(os.environ.get("START_FRAME", "0"))
num_chunks = int(os.environ.get("NUM_CHUNKS", "1"))
chunk_frames = int(os.environ.get("CHUNK_FRAMES", "81"))
# 轻量解析 VIDEO_NAME:勿 import run_replay_loop_two_chunk(会拉 torch/train/flash_attn)
sys.path.insert(0, os.path.join(eval_dir, "basic"))
from gt_pose_minimal import build_gt_trajectory_actions # noqa: E402
def valid(vn: str) -> bool:
for ch in range(num_chunks):
seg_start = start + ch * chunk_frames
if build_gt_trajectory_actions(dataset, vn, seg_start, chunk_frames) is None:
return False
return True
if wanted and wanted.upper() != "AUTO":
print(wanted if valid(wanted) else "")
raise SystemExit(0)
cands = []
jsons_dir = os.path.join(dataset, "jsons")
if os.path.isdir(jsons_dir):
for n in sorted(os.listdir(jsons_dir)):
if n.endswith(".json"):
cands.append(os.path.splitext(n)[0])
preferred = "AncientTempleEnv_0"
if preferred in cands:
cands.remove(preferred)
cands = [preferred] + cands
for vn in cands:
if valid(vn):
print(vn)
raise SystemExit(0)
print("")
PY
}
RESOLVED_VIDEO_NAME="$(_resolve_video_name "${VIDEO_NAME}")"
if [ -z "${RESOLVED_VIDEO_NAME}" ]; then
if [ -n "${VIDEO_NAME}" ] && [ "${VIDEO_NAME}" != "AUTO" ]; then
echo "[replay_gt] ERROR: VIDEO_NAME=${VIDEO_NAME} 不可用:缺少 GT actions(json 或帧段不足)。" >&2
else
echo "[replay_gt] ERROR: 未找到可用 video(DATASET/jsons 下无可用 GT actions)。" >&2
fi
exit 1
fi
if [ "${VIDEO_NAME}" != "${RESOLVED_VIDEO_NAME}" ]; then
echo "[replay_gt] 自动回退 VIDEO_NAME: ${VIDEO_NAME} -> ${RESOLVED_VIDEO_NAME}"
fi
VIDEO_NAME="${RESOLVED_VIDEO_NAME}"
python3 "${EVAL_DIR}/basic/check_dataset_gt_for_replay.py" \
--dataset "${DATASET}" \
--video "${VIDEO_NAME}" \
--start_frame "${START_FRAME}" \
--num_chunks "${NUM_CHUNKS}" \
--chunk_frames "${CHUNK_FRAMES_EFFECTIVE}" || exit 1
OUT_ROOT="${OUT_ROOT:-${CKPT_DIR}/evals_v2/basic}"
OUT_DIR="${OUT_ROOT}/replay_gt/${VIDEO_NAME}_start${START_FRAME}"
mkdir -p "${OUT_DIR}"
eval "$(python3 "${ENV_DIR}/memory_baseline_runtime.py" bash-export "${CKPT}")"
_default_ctx=1
[[ "${CKPT}" =~ (ctx_20|context_k20|ctx20) ]] && _default_ctx=20
[[ "${CKPT}" =~ (ctx_5|context_k5|ctx5) ]] && _default_ctx=5
[ -n "${CONTEXT_FRAMES_MEM_OVERRIDE:-}" ] && _default_ctx="${CONTEXT_FRAMES_MEM_OVERRIDE}"
CONTEXT_FRAMES_EFFECTIVE="${CONTEXT_FRAMES:-$_default_ctx}"
python3 "${EVAL_DIR}/basic/replay_gt_error.py" \
--ckpt "${CKPT}" \
--dataset_base "${DATASET}" \
--video_name "${VIDEO_NAME}" \
--start_frame "${START_FRAME}" \
--num_chunks "${NUM_CHUNKS}" \
--chunk_frames "${CHUNK_FRAMES_EFFECTIVE}" \
--context_frames "${CONTEXT_FRAMES_EFFECTIVE}" \
--sigma_shift "${SIGMA_SHIFT:-5}" \
--num_inference_steps "${NUM_INFERENCE_STEPS:-50}" \
--cfg_scale "${CFG_SCALE:-5.0}" \
--seed "${SEED:-42}" \
--output_dir "${OUT_DIR}" \
--write_csv
echo "Done. basic replay_gt output: ${OUT_DIR}"
|