#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" CONTAINER_NAME="llmc_codegpt_multilingual_gpu01" IMAGE="nvidia/cuda:12.2.2-devel-ubuntu22.04" RUN_ROOT="log_codegpt_multilingual_runs" TIMESTAMP="$(date +%Y%m%d_%H%M%S)" RUN_DIR="${RUN_ROOT}/${TIMESTAMP}" LATEST_LINK="${RUN_ROOT}/latest" NCCL_FS_DIR="/tmp/llmc_nccl_codegpt_multi_${TIMESTAMP}" EPOCHS=5 MICRO_BATCH_SIZE=32 SEQ_LEN=1024 NUM_PROCESSES=2 TOTAL_BATCH_SIZE=196608 LEARNING_RATE="0.0003" FINAL_LR_FRAC="0.1" WARMUP_STEPS=1000 WEIGHT_DECAY="0.1" RECOMPUTE=1 VAL_MAX_STEPS=20 TRAIN_PATTERN="dev/data/code_messages/code_messages_train_*.bin" VAL_PATTERN="dev/data/code_messages/code_messages_val_*.bin" LOAD_MODEL="codegpt_multilingual.bin" read -r TRAIN_TOKENS STEPS_PER_EPOCH MAX_STEPS <<<"$(python - <<'PY' import glob import struct files = sorted(glob.glob("dev/data/code_messages/code_messages_train_*.bin")) if not files: raise SystemExit("no training shards found") tokens = 0 for path in files: with open(path, "rb") as f: header = struct.unpack("256i", f.read(1024)) tokens += header[2] total_batch_size = 196608 epochs = 5 steps_per_epoch = tokens // total_batch_size print(tokens, steps_per_epoch, steps_per_epoch * epochs) PY )" VAL_EVERY=$((STEPS_PER_EPOCH / 16)) CHECKPOINT_EVERY="$STEPS_PER_EPOCH" SAMPLE_EVERY="$STEPS_PER_EPOCH" mkdir -p "$RUN_DIR" ln -sfn "$TIMESTAMP" "$LATEST_LINK" docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true { echo "host_launch_time=$(date -Is)" echo "container_name=$CONTAINER_NAME" echo "image=$IMAGE" echo "run_dir=$RUN_DIR" echo "train_tokens=$TRAIN_TOKENS" echo "epochs=$EPOCHS" echo "steps_per_epoch=$STEPS_PER_EPOCH" echo "max_steps=$MAX_STEPS" echo "checkpoint_every=$CHECKPOINT_EVERY" echo "sample_every=$SAMPLE_EVERY" echo "val_every=$VAL_EVERY" echo "val_max_steps=$VAL_MAX_STEPS" echo "total_batch_size=$TOTAL_BATCH_SIZE" echo "micro_batch_size=$MICRO_BATCH_SIZE" echo "seq_len=$SEQ_LEN" echo "learning_rate=$LEARNING_RATE" echo "final_lr_frac=$FINAL_LR_FRAC" echo "warmup_steps=$WARMUP_STEPS" echo "weight_decay=$WEIGHT_DECAY" echo "recompute=$RECOMPUTE" echo "load_model=$LOAD_MODEL" echo "train_pattern=$TRAIN_PATTERN" echo "val_pattern=$VAL_PATTERN" echo "git_commit=$(git rev-parse HEAD 2>/dev/null || true)" } > "$RUN_DIR/host_launch_meta.txt" docker run -d \ --name "$CONTAINER_NAME" \ --gpus '"device=0,1"' \ --ipc=host \ -u "$(id -u):$(id -g)" \ -v /raid/data/weifeng/llm.c:/workspace \ -w /workspace \ -e RUN_DIR="$RUN_DIR" \ -e NCCL_FS_DIR="$NCCL_FS_DIR" \ -e TRAIN_TOKENS="$TRAIN_TOKENS" \ -e EPOCHS="$EPOCHS" \ -e STEPS_PER_EPOCH="$STEPS_PER_EPOCH" \ -e MAX_STEPS="$MAX_STEPS" \ -e CHECKPOINT_EVERY="$CHECKPOINT_EVERY" \ -e SAMPLE_EVERY="$SAMPLE_EVERY" \ -e VAL_EVERY="$VAL_EVERY" \ -e VAL_MAX_STEPS="$VAL_MAX_STEPS" \ -e MICRO_BATCH_SIZE="$MICRO_BATCH_SIZE" \ -e SEQ_LEN="$SEQ_LEN" \ -e TOTAL_BATCH_SIZE="$TOTAL_BATCH_SIZE" \ -e LEARNING_RATE="$LEARNING_RATE" \ -e FINAL_LR_FRAC="$FINAL_LR_FRAC" \ -e WARMUP_STEPS="$WARMUP_STEPS" \ -e WEIGHT_DECAY="$WEIGHT_DECAY" \ -e RECOMPUTE="$RECOMPUTE" \ -e LOAD_MODEL="$LOAD_MODEL" \ -e TRAIN_PATTERN="$TRAIN_PATTERN" \ -e VAL_PATTERN="$VAL_PATTERN" \ "$IMAGE" \ bash -lc ' set -euo pipefail mkdir -p "$RUN_DIR" "$NCCL_FS_DIR" rm -f "$NCCL_FS_DIR"/* { echo "container_start_time=$(date -Is)" echo "hostname=$(hostname)" echo "run_dir=$RUN_DIR" echo "train_tokens=$TRAIN_TOKENS" echo "epochs=$EPOCHS" echo "steps_per_epoch=$STEPS_PER_EPOCH" echo "max_steps=$MAX_STEPS" echo "checkpoint_every=$CHECKPOINT_EVERY" echo "sample_every=$SAMPLE_EVERY" echo "val_every=$VAL_EVERY" echo "val_max_steps=$VAL_MAX_STEPS" echo "total_batch_size=$TOTAL_BATCH_SIZE" echo "micro_batch_size=$MICRO_BATCH_SIZE" echo "seq_len=$SEQ_LEN" echo "learning_rate=$LEARNING_RATE" echo "final_lr_frac=$FINAL_LR_FRAC" echo "warmup_steps=$WARMUP_STEPS" echo "weight_decay=$WEIGHT_DECAY" echo "recompute=$RECOMPUTE" echo "load_model=$LOAD_MODEL" echo "train_pattern=$TRAIN_PATTERN" echo "val_pattern=$VAL_PATTERN" echo nvcc --version echo nvidia-smi } > "$RUN_DIR/run_meta.txt" 2>&1 nvidia-smi \ --query-gpu=timestamp,index,name,utilization.gpu,memory.used,memory.total,power.draw,temperature.gpu \ --format=csv \ -l 30 > "$RUN_DIR/gpu_metrics.csv" 2>&1 & monitor_pid=$! cleanup() { kill "$monitor_pid" 2>/dev/null || true } trap cleanup EXIT rm -f train_gpt2cu make train_gpt2cu PRECISION=FP32 FORCE_NVCC_O=3 > "$RUN_DIR/build.log" 2>&1 common_args=( -e "$LOAD_MODEL" -i "$TRAIN_PATTERN" -j "$VAL_PATTERN" -o "$RUN_DIR" -b "$MICRO_BATCH_SIZE" -t "$SEQ_LEN" -d "$TOTAL_BATCH_SIZE" -x "$MAX_STEPS" -v "$VAL_EVERY" -m "$VAL_MAX_STEPS" -s "$SAMPLE_EVERY" -r "$RECOMPUTE" -c "$WEIGHT_DECAY" -l "$LEARNING_RATE" -q "$FINAL_LR_FRAC" -u "$WARMUP_STEPS" -n "$CHECKPOINT_EVERY" -f 0 -y 0 -pi fs -pf "$NCCL_FS_DIR" -pn 2 -pg 2 ) printf "%q " ./train_gpt2cu "${common_args[@]}" -pr 0 > "$RUN_DIR/command_rank0.txt" printf "\n" >> "$RUN_DIR/command_rank0.txt" printf "%q " ./train_gpt2cu "${common_args[@]}" -pr 1 > "$RUN_DIR/command_rank1.txt" printf "\n" >> "$RUN_DIR/command_rank1.txt" ./train_gpt2cu "${common_args[@]}" -pr 0 > "$RUN_DIR/rank0.log" 2>&1 & pid0=$! ./train_gpt2cu "${common_args[@]}" -pr 1 > "$RUN_DIR/rank1.log" 2>&1 & pid1=$! set +e wait -n "$pid0" "$pid1" first_status=$? if [[ "$first_status" -ne 0 ]]; then kill "$pid0" "$pid1" 2>/dev/null || true wait "$pid0" "$pid1" 2>/dev/null exit "$first_status" fi wait "$pid0" status0=$? wait "$pid1" status1=$? if [[ "$status0" -ne 0 || "$status1" -ne 0 ]]; then exit 1 fi ' echo "Launched $CONTAINER_NAME" echo "Run dir: $RUN_DIR" echo "Latest link: $LATEST_LINK"