File size: 5,849 Bytes
d13a83d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PROFILE="all"
CONDA_BIN="${CONDA_EXE:-}"
FLASH_WHEEL="${FLASH_ATTN_WHEEL:-}"
DRY_RUN=0
VERIFY=1

usage() {
  cat <<'EOF'
Usage: bash scripts/setup_envs.sh [options]

Create the pinned MR-IQA-2 environments without activating them.

Options:
  --profile NAME             inference, training, test, or all (default: all)
  --flash-attn-wheel PATH    validated wheel required by training/all
  --conda PATH               conda executable (default: CONDA_EXE or PATH)
  --no-verify                install without import/tests verification
  --dry-run                  print commands without changing the machine
  -h, --help                 show this help

Examples:
  bash scripts/setup_envs.sh --profile inference
  bash scripts/setup_envs.sh --profile test
  FLASH_ATTN_WHEEL=/abs/flash_attn.whl bash scripts/setup_envs.sh --profile all
EOF
}

die() {
  echo "error: $*" >&2
  exit 2
}

while (($#)); do
  case "$1" in
    --profile)
      (($# >= 2)) || die "--profile requires a value"
      PROFILE="$2"
      shift 2
      ;;
    --flash-attn-wheel)
      (($# >= 2)) || die "--flash-attn-wheel requires a path"
      FLASH_WHEEL="$2"
      shift 2
      ;;
    --conda)
      (($# >= 2)) || die "--conda requires a path"
      CONDA_BIN="$2"
      shift 2
      ;;
    --no-verify)
      VERIFY=0
      shift
      ;;
    --dry-run)
      DRY_RUN=1
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      die "unknown argument: $1"
      ;;
  esac
done

case "${PROFILE}" in
  inference|training|test|all) ;;
  *) die "unsupported profile: ${PROFILE}" ;;
esac

if [[ -z "${CONDA_BIN}" ]]; then
  CONDA_BIN="$(command -v conda || true)"
fi
if [[ -z "${CONDA_BIN}" ]]; then
  if ((DRY_RUN)); then
    CONDA_BIN="conda"
  else
    die "conda was not found; install Miniconda/Conda or pass --conda"
  fi
fi
if ((!DRY_RUN)) && [[ ! -x "${CONDA_BIN}" ]]; then
  die "conda executable is not runnable: ${CONDA_BIN}"
fi

print_command() {
  printf '+'
  printf ' %q' "$@"
  printf '\n'
}

run() {
  print_command "$@"
  if ((!DRY_RUN)); then
    "$@"
  fi
}

setup_conda_environment() {
  local definition="$1"
  local name="$2"
  local requirements="$3"
  run "${CONDA_BIN}" env update --file "${ROOT}/${definition}" --prune
  run "${CONDA_BIN}" run --no-capture-output -n "${name}" \
    python -m pip install --upgrade pip
  run "${CONDA_BIN}" run --no-capture-output -n "${name}" \
    python -m pip install -r "${ROOT}/${requirements}"
}

setup_gpu_environments() {
  setup_conda_environment \
    environment/actor-judge.yml \
    mr_iqa_actor_judge \
    requirements/actor-judge.txt
  setup_conda_environment \
    environment/editor.yml \
    mr_iqa_editor \
    requirements/editor.txt
}

verify_inference_environments() {
  run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_actor_judge \
    python -c 'import torch, transformers, swift, vllm; print("Actor/Judge imports OK")'
  run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_editor \
    python -c 'import diffusers, torch, transformers; print("Editor imports OK")'
}

require_flash_attention_wheel() {
  [[ -n "${FLASH_WHEEL}" ]] || die \
    "training requires --flash-attn-wheel or FLASH_ATTN_WHEEL"
  if ((!DRY_RUN)); then
    [[ -f "${FLASH_WHEEL}" ]] || die \
      "FlashAttention wheel does not exist: ${FLASH_WHEEL}"
  fi
}

install_flash_attention() {
  if [[ -n "${FLASH_ATTN_WHEEL_SHA256:-}" ]] && ((!DRY_RUN)); then
    local actual_sha
    actual_sha="$(python3 - "${FLASH_WHEEL}" <<'PY'
import hashlib
import sys
from pathlib import Path

path = Path(sys.argv[1])
print(hashlib.sha256(path.read_bytes()).hexdigest())
PY
)"
    [[ "${actual_sha}" == "${FLASH_ATTN_WHEEL_SHA256}" ]] || die \
      "FlashAttention wheel SHA256 does not match FLASH_ATTN_WHEEL_SHA256"
  fi
  run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_actor_judge \
    python -m pip install "${FLASH_WHEEL}"
  if ((VERIFY)); then
    run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_actor_judge \
      python -c 'import flash_attn; print("FlashAttention import OK")'
  fi
}

ensure_environment_template() {
  if [[ ! -e "${ROOT}/.env" ]]; then
    run cp "${ROOT}/.env.example" "${ROOT}/.env"
  fi
}

setup_test_environment() {
  run "${CONDA_BIN}" env update \
    --file "${ROOT}/environment/test.yml" --prune
  run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_release_test \
    python -m pip install --upgrade pip
  run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_release_test \
    python -m pip install 'torch==2.11.0' \
    --index-url https://download.pytorch.org/whl/cpu
  run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_release_test \
    python -m pip install -r "${ROOT}/requirements/test.txt"
  if ((VERIFY)); then
    run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_release_test \
      python -c 'import PIL, numpy, pytest, requests, torch; print("Test imports OK")'
    if [[ -f "${ROOT}/scripts/test_release.sh" && \
          -f "${ROOT}/scripts/check_release.py" ]]; then
      run "${CONDA_BIN}" run --no-capture-output -n mr_iqa_release_test \
        bash "${ROOT}/scripts/test_release.sh"
    fi
  fi
}

case "${PROFILE}" in
  inference)
    setup_gpu_environments
    ((VERIFY)) && verify_inference_environments
    ;;
  training)
    require_flash_attention_wheel
    setup_gpu_environments
    install_flash_attention
    ((VERIFY)) && verify_inference_environments
    ensure_environment_template
    ;;
  test)
    setup_test_environment
    ;;
  all)
    require_flash_attention_wheel
    setup_gpu_environments
    install_flash_attention
    ((VERIFY)) && verify_inference_environments
    ensure_environment_template
    setup_test_environment
    ;;
esac

echo "Environment setup complete for profile: ${PROFILE}"