# ═══════════════════════════════════════════════════════════ # 🔥 训练实时仪表盘 · training-dashboard.yml # ═══════════════════════════════════════════════════════════ # 签发: 铸渊 · ICE-GL-ZY001 # 版权: 国作登字-2026-A-00037559 · TCS-0002∞ # # GPU 服务器侧 progress-reporter.sh 通过 GitHub repository_dispatch # (event_type=training-progress) 推送训练心跳 → 本 workflow: # 1. 把 client_payload 合并到 data/training/state.json # 2. 渲染 README.md 中 TRAINING_DASHBOARD 段落 # 3. commit & push # # 触发: # - repository_dispatch · types=[training-progress, training-event] # - workflow_dispatch · 手动强制重渲染 # - schedule · 每 30 分钟兜底重渲染(即使没有心跳,也确保 README 不出陈旧) # ═══════════════════════════════════════════════════════════ name: 🔥 训练实时仪表盘 # ⚠️ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # 2026-05-03 D72:训练仪表盘已冻结。母模型训练转交 Notion 侧霜砚 + # 服务器直接协作,仓库不再接收训练心跳。 # # - repository_dispatch 触发已停用(不再回写 state.json) # - schedule 兜底已停用(不再每 30 分钟重渲染) # - 仅保留 workflow_dispatch 用于人工应急重渲染 # - 必须 confirm_override=true 才会真正写文件 # - README 训练仪表盘段落已切换为 D72 冻结占位 # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ on: # repository_dispatch 触发已停用 (D72) # repository_dispatch: # types: [training-progress, training-event] workflow_dispatch: inputs: confirm_override: description: '⚠️ 我已确认要解冻训练仪表盘并重新写入 state.json' type: boolean default: false force_render: description: '强制重渲染 README(即使 state.json 未变)' type: boolean default: true # schedule 触发已停用 (D72) # schedule: # - cron: '*/30 * * * *' permissions: contents: write concurrency: group: training-dashboard cancel-in-progress: false jobs: update-dashboard: name: 🔄 合并心跳 + 渲染首页 if: github.event.inputs.confirm_override == 'true' runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: 📥 Checkout uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: 📡 合并训练心跳事件 if: github.event_name == 'repository_dispatch' env: TRAINING_EVENT_JSON: ${{ toJson(github.event.client_payload) }} run: | echo "═══ 收到训练心跳 ═══" echo "$TRAINING_EVENT_JSON" | head -c 2000 echo "" echo "═══════════════════" node scripts/training/merge-event.js - name: 🎨 渲染 README 训练仪表盘 run: | node scripts/training/render-readme.js - name: 💾 提交变更 run: | git config user.name "zhuyuan-bot" git config user.email "zhuyuan@guanghulab.com" git add data/training/state.json README.md if git diff --cached --quiet; then echo "[dashboard] 无变更" exit 0 fi # 简短 commit 信息(带阶段+step) PHASE=$(node -e "console.log(JSON.parse(require('fs').readFileSync('data/training/state.json','utf8')).phase)") STEP=$(node -e "const s=JSON.parse(require('fs').readFileSync('data/training/state.json','utf8'));console.log((s.progress&&s.progress.step)||0)") TOTAL=$(node -e "const s=JSON.parse(require('fs').readFileSync('data/training/state.json','utf8'));console.log((s.progress&&s.progress.total_steps)||0)") MSG="🔥 training-dashboard · phase=${PHASE} step=${STEP}/${TOTAL} [skip ci]" git commit -m "$MSG" for i in 1 2 3 4 5; do git pull --rebase origin "${GITHUB_REF_NAME:-main}" && git push origin HEAD && exit 0 echo "⚠️ 推送冲突 第${i}次重试" sleep $((i * 3)) done echo "❌ 推送失败" exit 1 - name: 📝 摘要 if: always() run: | echo "## 训练仪表盘更新" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "- 触发: \`${{ github.event_name }}\`" >> $GITHUB_STEP_SUMMARY if [ "${{ github.event_name }}" = "repository_dispatch" ]; then echo "- 事件类型: \`${{ github.event.action }}\`" >> $GITHUB_STEP_SUMMARY fi echo "- 时间: $(date -u '+%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_STEP_SUMMARY if [ -f data/training/state.json ]; then echo "" >> $GITHUB_STEP_SUMMARY echo "### 当前状态" >> $GITHUB_STEP_SUMMARY echo '```json' >> $GITHUB_STEP_SUMMARY node -e "const s=JSON.parse(require('fs').readFileSync('data/training/state.json','utf8'));console.log(JSON.stringify({phase:s.phase,progress:s.progress,health:s.health.status},null,2))" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY fi