Instructions to use MagicCard/msrh-zindi-magic with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use MagicCard/msrh-zindi-magic with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
| # Launch all 19 inference runs to produce descriptive-named CSVs in candidate_csvs/ | |
| # | |
| # Usage: bash scripts/launch_all_predicts.sh | |
| # (auto-locates ROOT as the parent dir of this script) | |
| # | |
| # # or override the workspace root explicitly: | |
| # ROOT=/my/extract/path bash scripts/launch_all_predicts.sh | |
| # | |
| # Assumes the workspace at $ROOT holds: | |
| # - 19 LoRA adapters in $ROOT/checkpoints/<descriptive_name>/ | |
| # - Qwen base models in $ROOT/hub/{Qwen3.5-27B,Qwen3.6-27B,Qwen3-32B}/ | |
| # - vLLM env activated (`conda activate vllm`) | |
| # - At least 1 Γ 80GB GPU (H100/A100). 8 GPUs is the sweet spot (~2h); a | |
| # single GPU also works (~20-30h, purely sequential). Concurrency is | |
| # auto-capped at min(8, visible GPU count). | |
| # - Test JSONLs already present under $ROOT/LF/data/ | |
| # msrh_rag_test_k3_AfriE5_TV.json (K=3 base β NoFewshots only) | |
| # msrh_rag_test_k3_AfriE5_TV_fewshot_k3.json (K=3 fewshot) | |
| # msrh_rag_test_k3_AfriE5_TV_fewshot_k4.json (K=4 fewshot) | |
| # msrh_rag_test_k3_AfriE5_TV_fewshot_k5.json (K=5 fewshot) | |
| # msrh_rag_test_k3_AfriE5_TV_fewshot_k5_v8.json (K=5 v8) | |
| # msrh_rag_test_k3_AfriE5_TV_fewshot_k7.json (K=7 fewshot) | |
| # msrh_rag_test_k3_AfriE5_TV_fewshot_k7_v8.json (K=7 v8) | |
| # | |
| # Outputs: $ROOT/candidate_csvs/<descriptive_name>.csv (19 files, ready for ensemble) | |
| # | |
| # Scheduling policy: | |
| # - up to 8 predicts running concurrently, one per GPU | |
| # - staggered launches (40 s apart) to avoid concurrent vLLM engine-init races | |
| # - each launch is assigned to the LEAST-BUSY GPU (< 5 GB used), not a fixed rotation | |
| # - per-proc TORCHINDUCTOR_CACHE_DIR / TRITON_CACHE_DIR isolate compile caches | |
| # - failed adapters (no CSV or JSONL != 2618 rows) are retried once at the end | |
| # | |
| # NOTE: per-cand (max_model_len, max_num_seqs) match the original H100 chain scripts | |
| # that produced go.csv. Changing them alters vLLM paged-attention block sizing and | |
| # can shift greedy tokens. | |
| set -e | |
| ROOT="${ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}" | |
| CKPT_ROOT=$ROOT/checkpoints | |
| HUB_ROOT=$ROOT/hub | |
| TEST_DIR=$ROOT/LF/data | |
| OUT_DIR=$ROOT/candidate_csvs | |
| LOG_DIR=$ROOT/training_logs/predict | |
| mkdir -p $OUT_DIR $LOG_DIR | |
| # 19 predict jobs β pipe-delimited: NAME|BASE|TEST_JSON|MAX_LEN|MAX_SEQS | |
| JOBS=( | |
| "Qwen3.5-27B-3fewshots-bs64-3eps-ckpt-1200|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k3.json|6144|64" | |
| "Qwen3.5-27B-3fewshots-bs64-3eps-ckpt-1100|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k3.json|6144|64" | |
| "Qwen3.5-27B-3fewshots-bs64-5eps-ckpt-1200|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k3.json|6144|64" | |
| "Qwen3.5-27B-4fewshots-bs64-3eps-ckpt-1600|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k4.json|6144|64" | |
| "Qwen3.5-27B-5fewshots-bs64-3eps-v8prompt-ckpt-1500|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k5_v8.json|7168|64" | |
| "Qwen3.5-27B-7fewshots-bs64-3eps-ckpt-1600|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k7.json|9216|32" | |
| "Qwen3.5-27B-7fewshots-bs64-3eps-ckpt-1200|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k7.json|9216|32" | |
| "Qwen3.5-27B-NoFewshots-bs64-5eps-ckpt-2800|Qwen3.5-27B|msrh_rag_test_k3_AfriE5_TV.json|6144|32" | |
| "Qwen3.6-27B-3fewshots-bs64-3eps-ckpt-1600|Qwen3.6-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k3.json|6144|32" | |
| "Qwen3.6-27B-4fewshots-bs64-3eps-ckpt-1400|Qwen3.6-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k4.json|6144|64" | |
| "Qwen3.6-27B-5fewshots-bs64-3eps-ckpt-1200|Qwen3.6-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k5.json|7168|64" | |
| "Qwen3.6-27B-5fewshots-bs64-3eps-ckpt-1000|Qwen3.6-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k5.json|7168|64" | |
| "Qwen3.6-27B-7fewshots-bs64-3eps-ckpt-1600|Qwen3.6-27B|msrh_rag_test_k3_AfriE5_TV_fewshot_k7_v8.json|10240|32" | |
| "Qwen3.6-27B-NoFewshots-bs64-5eps-ckpt-2600|Qwen3.6-27B|msrh_rag_test_k3_AfriE5_TV.json|6144|32" | |
| "Qwen3-32B-3fewshots-bs64-3eps-ckpt-1400|Qwen3-32B|msrh_rag_test_k3_AfriE5_TV_fewshot_k3.json|6144|64" | |
| "Qwen3-32B-5fewshots-bs64-3eps-ckpt-1700|Qwen3-32B|msrh_rag_test_k3_AfriE5_TV_fewshot_k5.json|7168|64" | |
| "Qwen3-32B-7fewshots-bs64-3eps-ckpt-1600|Qwen3-32B|msrh_rag_test_k3_AfriE5_TV_fewshot_k7.json|9216|32" | |
| "Qwen3-32B-7fewshots-bs64-3eps-ckpt-1200|Qwen3-32B|msrh_rag_test_k3_AfriE5_TV_fewshot_k7.json|9216|32" | |
| "Qwen3-32B-NoFewshots-bs64-4eps-ckpt-6500|Qwen3-32B|msrh_rag_test_k3_AfriE5_TV.json|6144|32" | |
| ) | |
| # ββ helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Auto-detect visible GPU count (respects CUDA_VISIBLE_DEVICES if set). | |
| if [ -n "${CUDA_VISIBLE_DEVICES:-}" ]; then | |
| NUM_GPUS=$(echo "$CUDA_VISIBLE_DEVICES" | tr ',' '\n' | grep -c .) | |
| VISIBLE_GPUS=($(echo "$CUDA_VISIBLE_DEVICES" | tr ',' ' ')) | |
| else | |
| NUM_GPUS=$(nvidia-smi --query-gpu=index --format=csv,noheader 2>/dev/null | wc -l) | |
| VISIBLE_GPUS=($(seq 0 $((NUM_GPUS - 1)))) | |
| fi | |
| [ "$NUM_GPUS" -lt 1 ] && { echo "β no NVIDIA GPUs visible"; exit 1; } | |
| MAX_CONCURRENT=$(( NUM_GPUS < 8 ? NUM_GPUS : 8 )) | |
| echo "Detected $NUM_GPUS visible GPU(s) [${VISIBLE_GPUS[*]}]; up to $MAX_CONCURRENT predicts concurrently." | |
| # Pick the first visible GPU with < 5 GB used; return -1 if none free. | |
| free_gpu () { | |
| local g | |
| for g in "${VISIBLE_GPUS[@]}"; do | |
| local mem=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits -i $g 2>/dev/null | tr -d ' ') | |
| [ -z "$mem" ] && continue | |
| [ "$mem" -lt 5000 ] && { echo $g; return; } | |
| done | |
| echo -1 | |
| } | |
| predict_one () { | |
| local NAME="$1" BASE="$2" TEST_JSON="$3" MAX_LEN="$4" MAX_SEQS="$5" GPU="$6" | |
| local ADAPTER=$CKPT_ROOT/$NAME | |
| local WORK=$ROOT/_predict_workdir/$NAME | |
| local IND=/tmp/tinductor_${NAME} | |
| local TRI=/tmp/ttriton_${NAME} | |
| mkdir -p $WORK $IND $TRI | |
| if [ ! -f "$ADAPTER/adapter_model.safetensors" ]; then | |
| echo " β MISSING adapter: $ADAPTER (skipping)"; return | |
| fi | |
| if [ ! -f "$TEST_DIR/$TEST_JSON" ]; then | |
| echo " β MISSING test JSON: $TEST_DIR/$TEST_JSON (skipping $NAME)"; return | |
| fi | |
| echo " β [GPU $GPU] $NAME (max_len=$MAX_LEN max_seqs=$MAX_SEQS)" | |
| ( | |
| TORCHINDUCTOR_CACHE_DIR=$IND TRITON_CACHE_DIR=$TRI \ | |
| CUDA_VISIBLE_DEVICES=$GPU python $ROOT/scripts/vllm_predict_extra.py \ | |
| --base "$HUB_ROOT/$BASE" --adapter "$ADAPTER" \ | |
| --rag_test "$TEST_DIR/$TEST_JSON" \ | |
| --out_jsonl "$WORK/predictions.jsonl" \ | |
| --max_lora_rank 128 --max_new 512 \ | |
| --max_model_len $MAX_LEN --mem_util 0.90 --max_num_seqs $MAX_SEQS \ | |
| --temperature 0.0 --top_p 1.0 --best_of 1 --no_think \ | |
| > "$LOG_DIR/$NAME.log" 2>&1 \ | |
| && python $ROOT/scripts/jsonl_rowidx_to_csv.py \ | |
| --jsonl "$WORK/predictions.jsonl" \ | |
| --out_csv "$OUT_DIR/$NAME.csv" \ | |
| >> "$LOG_DIR/$NAME.log" 2>&1 \ | |
| && echo " β $NAME.csv" \ | |
| || echo " β $NAME FAILED (see $LOG_DIR/$NAME.log)" | |
| ) & | |
| } | |
| # ββ main scheduling loop: stagger + free-GPU assignment ββββββββββββββ | |
| launch_pass () { | |
| local -n QUEUE=$1 | |
| local pass_name="$2" | |
| echo "=== $pass_name (queue=${#QUEUE[@]}) ===" | |
| for JOB in "${QUEUE[@]}"; do | |
| while true; do | |
| local RUN=$(pgrep -c -f vllm_predict_extra 2>/dev/null) | |
| [ -z "$RUN" ] && RUN=0 | |
| if [ "$RUN" -ge "$MAX_CONCURRENT" ]; then sleep 20; continue; fi | |
| local G=$(free_gpu) | |
| if [ "$G" = "-1" ]; then sleep 20; continue; fi | |
| IFS="|" read -r NAME BASE TEST MLEN MSEQS <<< "$JOB" | |
| predict_one "$NAME" "$BASE" "$TEST" "$MLEN" "$MSEQS" "$G" | |
| sleep 40 # stagger to avoid concurrent init races | |
| break | |
| done | |
| done | |
| wait | |
| echo " β $pass_name done" | |
| } | |
| # ββ verify + retry βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| missing_jobs () { | |
| local -a MISS=() | |
| for JOB in "${JOBS[@]}"; do | |
| IFS="|" read -r NAME BASE TEST MLEN MSEQS <<< "$JOB" | |
| local CSV=$OUT_DIR/$NAME.csv | |
| local JSONL=$ROOT/_predict_workdir/$NAME/predictions.jsonl | |
| # OK if CSV exists AND JSONL has 2618 lines | |
| if [ -s "$CSV" ] && [ -s "$JSONL" ] && [ "$(wc -l < "$JSONL")" -eq 2618 ]; then | |
| continue | |
| fi | |
| MISS+=("$JOB") | |
| done | |
| printf '%s\n' "${MISS[@]}" | |
| } | |
| # Pass 1: launch all 19 | |
| PASS1=("${JOBS[@]}") | |
| launch_pass PASS1 "PASS 1 (all 19)" | |
| # Verify + retry up to 1 more pass on the ones that didn't produce a valid CSV | |
| mapfile -t MISS < <(missing_jobs) | |
| if [ "${#MISS[@]}" -gt 0 ] && [ -n "${MISS[0]:-}" ]; then | |
| echo | |
| echo "=== Retrying ${#MISS[@]} failed adapter(s) ===" | |
| # Give any lingering GPU state a moment to release | |
| sleep 30 | |
| RETRY=("${MISS[@]}") | |
| launch_pass RETRY "PASS 2 (retry)" | |
| fi | |
| # Final report | |
| echo | |
| FINAL_MISS=$(missing_jobs | wc -l) | |
| if [ "$FINAL_MISS" -eq 0 ] || [ "$FINAL_MISS" -eq 1 -a -z "$(missing_jobs)" ]; then | |
| echo "=== All 19 predictions complete ===" | |
| else | |
| echo "=== $FINAL_MISS adapter(s) STILL FAILED β check $LOG_DIR/*.log ===" | |
| missing_jobs | awk -F'|' '{print " β " $1}' | |
| fi | |
| ls -lh $OUT_DIR/ 2>/dev/null | tail -22 | |
| echo | |
| echo "Next step: python $ROOT/scripts/build_ensemble.py" | |