refactor: split submit_sft_via_cml.sh into submit_sft.sh + submit_cml_eval.sh
- submit_sft.sh: pure SFT submission, prints JobID and exits (no embedded watcher) - submit_cml_eval.sh: pure CML eval, reads workflow_id/version from config.yaml - jupyter_runtime write_text: rewrite to use Contents API instead of terminal websocket - SKILL.md: restrict trigger to explicit UI click only - program.md: update §5.2 docs to reflect two-script workflow Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+76
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
# 起 CML evaluation workflow(**只做这一件事**)。
|
||||
# workflow_id / version 都从 skills/model-iteration/assets/config.yaml 读,不在这里硬编码。
|
||||
#
|
||||
# 用法:
|
||||
# ./submit_cml_eval.sh <EVAL_RUNDIC> [MODEL_NEW] [MODEL_OLD]
|
||||
#
|
||||
# 默认值:
|
||||
# MODEL_NEW = $AUTORESEARCH_ROOT/sft_output(最新一轮 SFT 产物)
|
||||
# MODEL_OLD = /mnt/wangsenhao/verl_zk/qwen4b_cispo_wokl_add_bvt_2/global_step_5/actor/huggingface
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
EVAL_RUNDIC=${1:?usage: $0 <EVAL_RUNDIC> [MODEL_NEW] [MODEL_OLD]}
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT=${AUTORESEARCH_ROOT:-/mnt/wangsenhao/autoresearch-zk}
|
||||
MODEL_NEW=${2:-${MODEL_NEW:-$ROOT/sft_output}}
|
||||
MODEL_OLD=${3:-${MODEL_OLD:-/mnt/wangsenhao/verl_zk/qwen4b_cispo_wokl_add_bvt_2/global_step_5/actor/huggingface}}
|
||||
|
||||
# 定位 config.yaml:先看脚本旁边的 ../assets/,再看 skills/ 树
|
||||
find_config() {
|
||||
local candidates=(
|
||||
"$SCRIPT_DIR/../assets/config.yaml"
|
||||
"${ZK_AGENT_SKILLS_ROOT:-}/model-iteration/assets/config.yaml"
|
||||
"${AUTORESEARCH_CHAT_ROOT:-}/skills/model-iteration/assets/config.yaml"
|
||||
)
|
||||
local c
|
||||
for c in "${candidates[@]}"; do
|
||||
if [ -n "$c" ] && [ -f "$c" ]; then
|
||||
echo "$c"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
CONFIG=$(find_config) || {
|
||||
echo "[eval] ❌ 找不到 config.yaml(尝试过:$SCRIPT_DIR/../assets/、\$ZK_AGENT_SKILLS_ROOT/model-iteration/assets/、\$AUTORESEARCH_CHAT_ROOT/skills/...)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 极简 yaml 解析:只提 cml_eval.workflow_id / cml_eval.version(与后端 _read_workflow_version 风格保持一致)
|
||||
read_cml_eval_field() {
|
||||
local field=$1
|
||||
awk -v field="$field" '
|
||||
/^[^[:space:]#]/ { in_cml = ($1 == "cml_eval:") }
|
||||
in_cml && $1 == field { gsub(/^["\x27]|["\x27]$/, "", $2); print $2; exit }
|
||||
' "$CONFIG"
|
||||
}
|
||||
|
||||
EVAL_WORKFLOW_ID=$(read_cml_eval_field "workflow_id:")
|
||||
EVAL_VERSION=$(read_cml_eval_field "version:")
|
||||
|
||||
if [ -z "$EVAL_WORKFLOW_ID" ] || [ -z "$EVAL_VERSION" ]; then
|
||||
echo "[eval] ❌ 从 $CONFIG 读到的 cml_eval 不完整:workflow_id='$EVAL_WORKFLOW_ID' version='$EVAL_VERSION'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f ~/.cloudml-cli/.profile ]; then
|
||||
source ~/.cloudml-cli/.profile
|
||||
else
|
||||
echo "[eval] ❌ 未找到 ~/.cloudml-cli/.profile,请先安装并初始化 cml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[eval] EVAL_RUNDIC=$EVAL_RUNDIC workflow_id=$EVAL_WORKFLOW_ID version=$EVAL_VERSION (config: $CONFIG)"
|
||||
echo "[eval] MODEL_NEW=$MODEL_NEW"
|
||||
echo "[eval] MODEL_OLD=$MODEL_OLD"
|
||||
|
||||
cml workflow run \
|
||||
--workflow_id "$EVAL_WORKFLOW_ID" --version "$EVAL_VERSION" \
|
||||
--global_inputs runDic="$EVAL_RUNDIC" \
|
||||
--global_inputs model_path_new="$MODEL_NEW" \
|
||||
--global_inputs model_path_old="$MODEL_OLD"
|
||||
|
||||
echo "[eval] ✅ 已提交 workflow$EVAL_RUNDIC,产物在 /mnt/xiaoai-zk-model-train-tj5/workflow5/workflow${EVAL_RUNDIC}/"
|
||||
Reference in New Issue
Block a user