File size: 5,277 Bytes
df529cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env bash
# Build real DePlot evidence and calibrate the 7B confidence gate on ChartQA val.
set -euo pipefail

PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "${PROJECT_DIR}"

PYTHON_ENV="${PYTHON_ENV:-${PROJECT_DIR}/.venv}"
PYTHON_BIN="${PYTHON_BIN:-${PYTHON_ENV}/bin/python}"
TORCHRUN_BIN="${TORCHRUN_BIN:-${PYTHON_ENV}/bin/torchrun}"
RAW_VALIDATION_JSON="${RAW_VALIDATION_JSON:-${PROJECT_DIR}/data/images/chartqa/json/val.json}"
DEPLOT_VALIDATION_JSON="${DEPLOT_VALIDATION_JSON:-${PROJECT_DIR}/data/chartqa/teacher_gate/llava_onevision_7b_deplot_greedy/validation_real_deplot.json}"
VALIDATION_JSONL="${VALIDATION_JSONL:-${PROJECT_DIR}/data/chartqa/teacher_gate/llava_onevision_7b_deplot_greedy/validation.jsonl}"
TRAIN_JSONL="${TRAIN_JSONL:-${PROJECT_DIR}/data/chartqa/teacher_gate/llava_onevision_7b_deplot_greedy/train.jsonl}"
DEPLOT_CACHE="${DEPLOT_CACHE:-${PROJECT_DIR}/data/chartqa/teacher_gate/llava_onevision_7b_deplot_greedy/validation_deplot_cache.json}"
DEPLOT_PATH="${DEPLOT_PATH:-/data/lyf/.cache/huggingface/manual/google-deplot-6e76d624}"
TEACHER_PATH="${TEACHER_PATH:-/data/lyf/.cache/huggingface/hub/models--llava-hf--llava-onevision-qwen2-7b-ov-hf/snapshots/0d50680527681998e456c7b78950205bedd8a068}"
PROCESSOR_PATH="${PROCESSOR_PATH:-/data/lyf/.cache/huggingface/manual/llava-onevision-qwen2-7b-ov-hf-processor-0d506805}"
MIN_FREE_MIB="${MIN_FREE_MIB:-80000}"
MAX_USED_MIB="${MAX_USED_MIB:-2048}"
MAX_UTILIZATION="${MAX_UTILIZATION:-20}"
BATCH_SIZE="${BATCH_SIZE:-4}"
WAIT_FOR_GPUS="${WAIT_FOR_GPUS:-1}"
WAIT_SECONDS="${WAIT_SECONDS:-30}"

for required_path in \
  "${PYTHON_BIN}" "${TORCHRUN_BIN}" "${RAW_VALIDATION_JSON}" \
  "${DEPLOT_PATH}" "${TEACHER_PATH}" "${PROCESSOR_PATH}"; do
  if [[ ! -e "${required_path}" ]]; then
    echo "Required validation-calibration path does not exist: ${required_path}" >&2
    exit 2
  fi
done

select_idle_gpus() {
  {
    nvidia-smi \
      --query-gpu=index,memory.used,memory.free,utilization.gpu \
      --format=csv,noheader,nounits
  } | awk -F, \
      -v max_used="${MAX_USED_MIB}" \
      -v min_free="${MIN_FREE_MIB}" \
      -v max_util="${MAX_UTILIZATION}" '
        {
          gsub(/[[:space:]]/, "", $1)
          if (($2 + 0) <= max_used && ($3 + 0) >= min_free && ($4 + 0) <= max_util) {
            print $1
          }
        }
      ' | paste -sd, -
}

if [[ "${WAIT_FOR_GPUS}" != "0" && "${WAIT_FOR_GPUS}" != "1" ]]; then
  echo "WAIT_FOR_GPUS must be 0 or 1, got ${WAIT_FOR_GPUS}." >&2
  exit 2
fi
if [[ -z "${TARGET_GPUS:-}" ]]; then
  while true; do
    TARGET_GPUS="$(select_idle_gpus)"
    if [[ -n "${TARGET_GPUS}" ]]; then
      break
    fi
    if [[ "${WAIT_FOR_GPUS}" != "1" ]]; then
      echo "No GPU satisfies the validation-calibration idle/capacity thresholds." >&2
      exit 3
    fi
    printf '[%s] waiting for a truly idle GPU for validation calibration.\n' "$(date -Is)"
    sleep "${WAIT_SECONDS}"
  done
fi

IFS=',' read -r -a selected_gpu_list <<< "${TARGET_GPUS}"
NUM_PROCESSES="${#selected_gpu_list[@]}"
mkdir -p "$(dirname "${VALIDATION_JSONL}")"
LOG_PATH="${VALIDATION_JSONL}.build.log"
DEPLOT_INPUT="${RAW_VALIDATION_JSON}"
if [[ -s "${DEPLOT_VALIDATION_JSON}" ]]; then
  DEPLOT_INPUT="${DEPLOT_VALIDATION_JSON}"
fi

printf '[%s] validation calibration: GPUs=%s ranks=%s deplot_input=%s output=%s\n' \
  "$(date -Is)" "${TARGET_GPUS}" "${NUM_PROCESSES}" "${DEPLOT_INPUT}" "${VALIDATION_JSONL}" \
  | tee -a "${LOG_PATH}"

env \
  -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY \
  -u http_proxy -u https_proxy -u all_proxy \
  CUDA_VISIBLE_DEVICES="${TARGET_GPUS}" \
  HF_HUB_OFFLINE=1 \
  TRANSFORMERS_OFFLINE=1 \
  TOKENIZERS_PARALLELISM=false \
  "${PYTHON_BIN}" scripts/build_visual_facts_chartqa_deplot.py \
  --input "${DEPLOT_INPUT}" \
  --output "${DEPLOT_VALIDATION_JSON}" \
  --cache "${DEPLOT_CACHE}" \
  --model-id "${DEPLOT_PATH}" \
  --dtype float32 \
  --batch-size 8 \
  --worker-chunk-size 128 \
  --max-new-tokens 384 \
  --only-missing \
  --all-gpus \
  2>&1 | tee -a "${LOG_PATH}"

env \
  -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY \
  -u http_proxy -u https_proxy -u all_proxy \
  CUDA_VISIBLE_DEVICES="${TARGET_GPUS}" \
  HF_HUB_OFFLINE=1 \
  TRANSFORMERS_OFFLINE=1 \
  TOKENIZERS_PARALLELISM=false \
  "${TORCHRUN_BIN}" --standalone --nproc_per_node="${NUM_PROCESSES}" \
  scripts/preprocess_chartqa_teacher_gate.py \
  --input "${DEPLOT_VALIDATION_JSON}" \
  --output "${VALIDATION_JSONL}" \
  --split validation \
  --teacher-model "${TEACHER_PATH}" \
  --processor-model "${PROCESSOR_PATH}" \
  --providers visual_facts_deplot \
  --batch-size "${BATCH_SIZE}" \
  --max-new-tokens 96 \
  --repetition-penalty 1.0 \
  --require-real-deplot \
  --no-human-only \
  --expected-samples 1920 \
  --calibrate \
  --target-precision 0.90 \
  --min-coverage 0.10 \
  --log-every 100 \
  2>&1 | tee -a "${LOG_PATH}"

if [[ -s "${TRAIN_JSONL}" && -s "${TRAIN_JSONL}.manifest.json" ]]; then
  "${PYTHON_BIN}" scripts/reapply_chartqa_teacher_gate_calibration.py \
    --train-cache "${TRAIN_JSONL}" \
    --calibration-manifest "${VALIDATION_JSONL}.manifest.json" \
    2>&1 | tee -a "${LOG_PATH}"
else
  printf '[%s] train cache is not present yet; no train decision reapplication needed.\n' \
    "$(date -Is)" | tee -a "${LOG_PATH}"
fi