mirror of
https://github.com/kvcache-ai/ktransformers.git
synced 2026-10-18 06:31:45 +08:00
7c35863f62
* ci: add isolated model E2E acceptance for PR wheels and PyPI * ci: recheck GPU occupancy before each model starts * ci: disable inherited container healthchecks during acceptance * ci: wait for free GPUs before native import validation * docs: record qj5090 acceptance infrastructure validation * ci: add immutable candidate and public PyPI release acceptance gates
184 lines
6.3 KiB
YAML
184 lines
6.3 KiB
YAML
name: Model E2E acceptance (PR / PyPI)
|
||
|
||
# Separate from release workflows: this workflow cannot upload packages.
|
||
# Only maintainers dispatch reviewed SHAs; never execute pull_request_target code.
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
mode:
|
||
description: '验收对象:pr 为候选 wheels,pypi 为公开安装'
|
||
type: choice
|
||
options: [pypi, pr]
|
||
default: pypi
|
||
version:
|
||
description: 'PyPI 的 ktransformers 版本;latest 按用户默认安装'
|
||
type: string
|
||
default: latest
|
||
pr_repository:
|
||
description: 'PR 所属四仓之一'
|
||
type: choice
|
||
options: [kvcache-ai/ktransformers, kvcache-ai/sglang, kvcache-ai/transformers, kvcache-ai/accelerate]
|
||
default: kvcache-ai/ktransformers
|
||
pr_number:
|
||
description: 'PR 编号(pr 模式必填)'
|
||
type: string
|
||
default: ''
|
||
pr_sha:
|
||
description: '已审阅批准的完整 PR head SHA(pr 模式必填)'
|
||
type: string
|
||
default: ''
|
||
build_run_id:
|
||
description: '可信 main 构建流程的 run ID,包含 model-e2e-candidate artifact'
|
||
type: string
|
||
default: ''
|
||
workflow_call:
|
||
inputs:
|
||
mode:
|
||
type: string
|
||
default: pypi
|
||
version:
|
||
type: string
|
||
default: latest
|
||
pr_repository:
|
||
type: string
|
||
default: kvcache-ai/ktransformers
|
||
pr_number:
|
||
type: string
|
||
default: ''
|
||
pr_sha:
|
||
type: string
|
||
default: ''
|
||
build_run_id:
|
||
type: string
|
||
default: ''
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
# Deliberately no shared Actions concurrency group: GitHub may replace an
|
||
# existing pending run. The runner queue + host-wide flock preserve waiting jobs.
|
||
jobs:
|
||
prepare:
|
||
if: github.repository == 'kvcache-ai/ktransformers' && github.ref == 'refs/heads/main'
|
||
runs-on: ubuntu-24.04
|
||
timeout-minutes: 20
|
||
permissions:
|
||
contents: read
|
||
actions: read
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
persist-credentials: false
|
||
- uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.12'
|
||
- name: Freeze the approved test identity (no PR code execution)
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
ENABLED: ${{ vars.KT_MODEL_E2E_ENABLED }}
|
||
MODE: ${{ inputs.mode }}
|
||
VERSION: ${{ inputs.version }}
|
||
PR_REPOSITORY: ${{ inputs.pr_repository }}
|
||
PR_NUMBER: ${{ inputs.pr_number }}
|
||
PR_SHA: ${{ inputs.pr_sha }}
|
||
BUILD_RUN_ID: ${{ inputs.build_run_id }}
|
||
BUILD_WORKFLOW: ${{ vars.KT_MODEL_E2E_BUILD_WORKFLOW }}
|
||
run: |
|
||
python .github/model-e2e/prepare.py
|
||
mkdir input
|
||
mv request.json input/request.json
|
||
- name: Download final candidates from the approved build
|
||
if: inputs.mode == 'pr'
|
||
uses: actions/download-artifact@v4
|
||
with:
|
||
name: model-e2e-candidate
|
||
path: input/candidate
|
||
run-id: ${{ inputs.build_run_id }}
|
||
github-token: ${{ github.token }}
|
||
- name: Check wheel hashes and source lock
|
||
if: inputs.mode == 'pr'
|
||
run: |
|
||
python - <<'PY'
|
||
import json, sys
|
||
sys.path.insert(0, '.github/model-e2e')
|
||
from contracts import verify_candidate
|
||
verify_candidate('input/candidate', json.load(open('input/request.json')))
|
||
PY
|
||
- uses: actions/upload-artifact@v4
|
||
with:
|
||
name: model-e2e-input-${{ github.run_id }}-${{ github.run_attempt }}
|
||
path: input/
|
||
if-no-files-found: error
|
||
retention-days: 7
|
||
|
||
gpu:
|
||
needs: prepare
|
||
# An administrator must provision the no-credentials runner account and
|
||
# protected environment before assigning this new label. Existing release
|
||
# runners must NOT receive the label without the documented isolation audit.
|
||
environment: qj5090-model-e2e
|
||
runs-on: [self-hosted, linux, x64, gpu, kt-model-e2e]
|
||
timeout-minutes: 1100
|
||
permissions:
|
||
contents: read
|
||
actions: read
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
persist-credentials: false
|
||
path: harness
|
||
- uses: actions/download-artifact@v4
|
||
with:
|
||
name: model-e2e-input-${{ github.run_id }}-${{ github.run_attempt }}
|
||
path: input
|
||
- name: Queue, install fresh packages, and run the three model tests
|
||
env:
|
||
HOST_CONFIG: ${{ vars.KT_MODEL_E2E_HOST_CONFIG || '/etc/ktransformers/model-e2e/qj5090.json' }}
|
||
CONTROLLER_PYTHON: ${{ vars.KT_MODEL_E2E_PYTHON || 'python3.12' }}
|
||
run: |
|
||
set -euo pipefail
|
||
test "$("$CONTROLLER_PYTHON" -c 'import sys; print(sys.version_info >= (3, 11))')" = True
|
||
test_root="$(mktemp -d "$RUNNER_TEMP/kt-model-e2e.XXXXXXXX")"
|
||
echo "E2E_OUTPUT=$test_root/output" >> "$GITHUB_ENV"
|
||
"$CONTROLLER_PYTHON" harness/.github/model-e2e/host.py \
|
||
--config "$HOST_CONFIG" --input "$GITHUB_WORKSPACE/input" \
|
||
--output "$test_root/output"
|
||
- name: Retain evidence only (not model weights, adapters, or the venv)
|
||
if: always() && env.E2E_OUTPUT != ''
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: model-e2e-evidence-${{ github.run_id }}-${{ github.run_attempt }}
|
||
path: ${{ env.E2E_OUTPUT }}/evidence/
|
||
if-no-files-found: warn
|
||
retention-days: 30
|
||
|
||
report:
|
||
if: always()
|
||
needs: [prepare, gpu]
|
||
runs-on: ubuntu-24.04
|
||
timeout-minutes: 10
|
||
permissions:
|
||
contents: read
|
||
actions: read
|
||
statuses: write
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
persist-credentials: false
|
||
- uses: actions/download-artifact@v4
|
||
if: needs.prepare.result == 'success'
|
||
with:
|
||
name: model-e2e-input-${{ github.run_id }}-${{ github.run_attempt }}
|
||
path: input
|
||
- uses: actions/download-artifact@v4
|
||
if: needs.gpu.result == 'success' || needs.gpu.result == 'failure'
|
||
continue-on-error: true
|
||
with:
|
||
name: model-e2e-evidence-${{ github.run_id }}-${{ github.run_attempt }}
|
||
path: evidence
|
||
- name: Summarize and report to the approved KT PR SHA
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
GPU_JOB_RESULT: ${{ needs.gpu.result }}
|
||
run: python3 .github/model-e2e/report.py
|