File size: 5,960 Bytes
8c9ba62 | 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 141 142 143 144 | #!/usr/bin/env bash
# Prepare this bundle for training. Run once, from the bundle root:
#
# bash scripts/setup.sh [options]
#
# Options:
# --with-deps also pip-install runtime dependencies from tcod/ (torch,
# vllm, flash-attn, ...). Skip this if the node already has
# a working Trinity/TCOD environment -- the default only
# installs the vendored tcod package itself, with --no-deps.
# --models DIR reuse models already on the node. Symlinks DIR/Qwen3-1.7B
# and DIR/Qwen3-32B into ./models instead of downloading.
# --skip-models do not download or link models (you will wire ./models up
# yourself before running).
#
# What it does, in order:
# 1. sanity-checks python / java
# 2. pip-installs the vendored tcod/ (editable, --no-deps by default)
# 3. copies overlay/trinity/ over tcod/trinity/ -- this is the FutureBridge
# workflow overlay; see NOTICE
# 4. verifies all five ScienceWorld workflow classes import
# 5. puts Qwen3-1.7B and Qwen3-32B under ./models
# 6. downloads the ScienceWorld task split into ./data/scienceworld
# 7. creates ./outputs/{tmp,ray_tmp,buffers,checkpoints,logs}
#
# Idempotent: every step checks before doing work, so re-running after a partial
# failure is safe.
set -euo pipefail
BUNDLE=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
cd "$BUNDLE"
WITH_DEPS=false
SKIP_MODELS=false
EXT_MODELS=""
while [ $# -gt 0 ]; do
case "$1" in
--with-deps) WITH_DEPS=true; shift ;;
--skip-models) SKIP_MODELS=true; shift ;;
--models) EXT_MODELS=${2:-}; shift 2 ;;
*) echo "unknown option: $1" >&2; exit 2 ;;
esac
done
log() { printf '\n[setup] %s\n' "$*"; }
die() { printf '[setup] ERROR: %s\n' "$*" >&2; exit 1; }
log "bundle root: $BUNDLE"
# ---------------------------------------------------------------- sanity ----
command -v python >/dev/null 2>&1 || die "no 'python' on PATH"
PYV=$(python -c 'import sys; print("%d.%d" % sys.version_info[:2])')
log "python $PYV"
[ "$PYV" = "3.10" ] || log "WARNING: the release targets python 3.10, found $PYV"
if command -v java >/dev/null 2>&1; then
log "java: $(java -version 2>&1 | head -1)"
else
log "WARNING: no 'java' on PATH -- ScienceWorld starts a JVM per episode and"
log " will fail at runtime. Needs Java 17+ (e.g. 'module load openjdk')."
fi
# ------------------------------------------------------------ tcod + deps ----
[ -d tcod/trinity ] || die "tcod/ is missing or incomplete -- re-download the bundle"
if [ "$WITH_DEPS" = true ]; then
log "installing runtime dependencies (--with-deps)"
# flash-attn compiles against an installed torch, so it cannot come from the
# same resolution pass; install it last, without build isolation.
TMP_REQ=$(mktemp)
grep -v '^flash-attn' requirements.txt > "$TMP_REQ"
python -m pip install -r "$TMP_REQ"
rm -f "$TMP_REQ"
python -m pip install flash-attn==2.8.1 --no-build-isolation || \
log "WARNING: flash-attn failed to build; training may still work without it"
fi
log "installing the vendored tcod package (editable, --no-deps)"
python -m pip install -e tcod --no-deps
python -c "import scienceworld" 2>/dev/null \
|| { log "installing scienceworld==1.2.2"; python -m pip install 'scienceworld==1.2.2'; }
# ---------------------------------------------------------------- overlay ----
log "applying the FutureBridge workflow overlay onto tcod/"
cp -R overlay/trinity/. tcod/trinity/
log "verifying the five ScienceWorld workflow classes import"
python - <<'EOF'
import importlib
mods = [
("trinity.common.workflows.envs.TCOD.scienceworld.OPD_workflow",
"OnPolicyDistillVerlAgentScienceworldWorkflow"),
("trinity.common.workflows.envs.TCOD.scienceworld.guided_opd_workflow",
"GuidedOPDScienceworldWorkflow"),
("trinity.common.workflows.envs.TCOD.scienceworld.TCOD_b2f_workflow",
"TCOD_b2f_scienceworld_workflow"),
("trinity.common.workflows.envs.TCOD.scienceworld.TCOD_f2b_workflow",
"TCOD_f2b_scienceworld_workflow"),
("trinity.common.workflows.envs.TCOD.scienceworld.futurebridge_workflow",
"FutureBridgeScienceWorldWorkflow"),
]
for mod, cls in mods:
getattr(importlib.import_module(mod), cls)
print(f" OK {cls}")
EOF
# ----------------------------------------------------------------- models ----
mkdir -p models
if [ "$SKIP_MODELS" = true ]; then
log "skipping models (--skip-models); wire ./models/Qwen3-1.7B and ./models/Qwen3-32B up yourself"
elif [ -n "$EXT_MODELS" ]; then
log "linking models from $EXT_MODELS"
for m in Qwen3-1.7B Qwen3-32B; do
[ -d "$EXT_MODELS/$m" ] || die "$EXT_MODELS/$m does not exist"
ln -sfn "$EXT_MODELS/$m" "models/$m"
echo " linked models/$m -> $EXT_MODELS/$m"
done
else
HF_CLI=$(command -v hf || command -v huggingface-cli || true)
[ -n "$HF_CLI" ] || die "neither 'hf' nor 'huggingface-cli' found (pip install huggingface_hub), \
or re-run with --models DIR / --skip-models"
for pair in "Qwen/Qwen3-1.7B:Qwen3-1.7B" "Qwen/Qwen3-32B:Qwen3-32B"; do
repo=${pair%%:*}; name=${pair##*:}
if [ -f "models/$name/config.json" ]; then
log "models/$name already present, skipping"
else
log "downloading $repo -> models/$name"
"$HF_CLI" download "$repo" --local-dir "models/$name"
fi
done
fi
# ------------------------------------------------------------------- data ----
log "preparing the ScienceWorld task split"
python scripts/prepare_data.py --out data/scienceworld
# ---------------------------------------------------------------- outputs ----
mkdir -p outputs/tmp outputs/ray_tmp outputs/buffers outputs/checkpoints outputs/logs
log "setup complete."
log "next: bash scripts/run.sh ftb (or opd | guided_opd | tcod_b2f | tcod_f2b)"
|