diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index bf8d62f5a1..5bef6bfac2 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -6,5 +6,6 @@ # them. self-hosted-runner: labels: - - prod-aisimulate-default-amd64-v1 - - prod-aisimulate-default-arm64-v1 + - prod-aisim-default-amd64-v1 + - prod-aisim-default-arm64-v1 + - dynamo-cpu-4gi-amd64 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b61af95ba..0a59a481cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -267,11 +267,11 @@ jobs: matrix: include: - arch: amd64 - runner: prod-aisimulate-default-amd64-v1 + runner: prod-aisim-default-amd64-v1 cargo_deny_target: x86_64-unknown-linux-musl cargo_deny_sha256: 0e8c2aa59128612c90d9e09c02204e912f29a5b8d9a64671b94608cbe09e064f - arch: arm64 - runner: prod-aisimulate-default-arm64-v1 + runner: prod-aisim-default-arm64-v1 cargo_deny_target: aarch64-unknown-linux-musl cargo_deny_sha256: 2b3567a60b7491c159d1cef8b7d8479d1ad2a31e29ef49462634ad4552fcc77d runs-on: ${{ matrix.runner }} @@ -279,7 +279,7 @@ jobs: container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -316,11 +316,11 @@ jobs: fail-fast: false matrix: arch: [amd64, arm64] - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -335,14 +335,14 @@ jobs: name: Rust feature modes needs: [fast-ci, select-full-ci] if: ${{ needs.select-full-ci.outputs.rust_feature_modes == 'true' }} - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 15 env: CARGO_TARGET_DIR: ${{ github.workspace }}/target-feature-tests container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -381,11 +381,11 @@ jobs: fail-fast: false matrix: arch: [amd64, arm64] - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -412,11 +412,11 @@ jobs: fail-fast: false matrix: arch: [amd64, arm64] - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -461,11 +461,11 @@ jobs: fail-fast: false matrix: arch: [amd64, arm64] - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -600,12 +600,12 @@ jobs: - arch: arm64 # quay.io/pypa/manylinux_2_28_aarch64:2026.08.24-1 container_image: quay.io/pypa/manylinux_2_28_aarch64@sha256:29a6ceb78de5b00494e6e7456a72782a4cb54238de102e7491d15fe47789b4d1 - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 timeout-minutes: 10 container: image: ${{ matrix.container_image }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -655,12 +655,12 @@ jobs: - {suite: cli-build, group: 4, groups: 4} - {suite: support-matrix, group: 1, groups: 1} - {suite: tools-build, group: 1, groups: 1} - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 timeout-minutes: 15 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -776,12 +776,12 @@ jobs: needs.select-full-ci.result == 'success' && needs.select-full-ci.outputs.application_wheel == 'true' }} - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 15 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -798,7 +798,7 @@ jobs: name: Python ${{ matrix.python-version }} compatibility needs: [fast-ci, select-full-ci] if: ${{ needs.select-full-ci.outputs.python_compatibility == 'true' }} - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 30 strategy: fail-fast: false @@ -807,7 +807,7 @@ jobs: container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -831,12 +831,12 @@ jobs: name: Engine Golden Regression needs: [fast-ci, select-full-ci] if: ${{ needs.select-full-ci.outputs.engine_golden_regression == 'true' }} - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 45 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -886,11 +886,11 @@ jobs: - arch: arm64 # quay.io/pypa/manylinux_2_28_aarch64:2026.08.24-1 container_image: quay.io/pypa/manylinux_2_28_aarch64@sha256:29a6ceb78de5b00494e6e7456a72782a4cb54238de102e7491d15fe47789b4d1 - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 container: image: ${{ matrix.container_image }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 diff --git a/.github/workflows/collector-check.yml b/.github/workflows/collector-check.yml index 51e9ff46ce..46533822b4 100644 --- a/.github/workflows/collector-check.yml +++ b/.github/workflows/collector-check.yml @@ -26,12 +26,12 @@ concurrency: jobs: check: name: Check collector data - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 20 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - name: Checkout code @@ -57,13 +57,13 @@ jobs: cross-backend-consistency: name: Perf data sanity (informational) - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 25 continue-on-error: true container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - name: Checkout code diff --git a/.github/workflows/e2e-accuracy-branch.yml b/.github/workflows/e2e-accuracy-branch.yml index edf3de6db6..89982b0fea 100644 --- a/.github/workflows/e2e-accuracy-branch.yml +++ b/.github/workflows/e2e-accuracy-branch.yml @@ -45,7 +45,7 @@ permissions: jobs: wheel: name: Prepare exact accuracy wheel - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 120 permissions: contents: read @@ -135,11 +135,11 @@ jobs: measurements: name: Prepare shared E2E measurements timeout-minutes: 120 - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -189,13 +189,13 @@ jobs: max-parallel: 4 matrix: shard: [0, 1, 2, 3] - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 360 container: # The runner executes as non-root; use its sudo-enabled CI image. image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner env: OPENBLAS_NUM_THREADS: '1' @@ -313,11 +313,11 @@ jobs: name: Qualify E2E accuracy (${{ inputs.artifact_key }}) needs: [wheel, shards] timeout-minutes: 30 - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -397,12 +397,12 @@ jobs: max-parallel: 2 matrix: shard: [0, 1] - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 360 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner env: OPENBLAS_NUM_THREADS: '1' @@ -485,12 +485,12 @@ jobs: qualify-agentx: name: Qualify AgentX accuracy (${{ inputs.artifact_key }}) needs: agentx - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 30 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 diff --git a/.github/workflows/fpe-release-qualify.yml b/.github/workflows/fpe-release-qualify.yml index 79730ec4eb..2e66255b70 100644 --- a/.github/workflows/fpe-release-qualify.yml +++ b/.github/workflows/fpe-release-qualify.yml @@ -26,7 +26,7 @@ jobs: prepare: name: Build and identify release FPE wheel if: github.ref == 'refs/heads/main' - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 30 container: # Same pinned manylinux toolchain as the main FPE producer. @@ -75,7 +75,7 @@ jobs: generate: name: Release FPE (${{ matrix.shard.system }}, ${{ matrix.shard.backend }}) needs: prepare - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 480 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} diff --git a/.github/workflows/fpe-support-matrix.yml b/.github/workflows/fpe-support-matrix.yml index ceda22708c..7bb02e64ec 100644 --- a/.github/workflows/fpe-support-matrix.yml +++ b/.github/workflows/fpe-support-matrix.yml @@ -35,13 +35,13 @@ env: jobs: prepare-wheel: name: Prepare exact FPE wheel - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 30 container: # quay.io/pypa/manylinux_2_28_x86_64:2026.08.24-1 image: quay.io/pypa/manylinux_2_28_x86_64@sha256:4dc41da7df20400310c80d162a2fe2d2c2f3d9734d8dec20f6b9843711618deb env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner outputs: wheel-sha256: ${{ steps.digest.outputs.sha256 }} @@ -150,12 +150,12 @@ jobs: generate: name: FPE matrix (${{ matrix.shard.system }}, ${{ matrix.shard.backend }}) needs: [discover-shards, prepare-wheel] - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 480 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner strategy: fail-fast: false diff --git a/.github/workflows/fpm-accuracy-branch.yml b/.github/workflows/fpm-accuracy-branch.yml index 6c8c28e288..7a3f5f9426 100644 --- a/.github/workflows/fpm-accuracy-branch.yml +++ b/.github/workflows/fpm-accuracy-branch.yml @@ -29,7 +29,7 @@ permissions: jobs: wheel: name: Prepare exact accuracy wheel - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 120 permissions: contents: read @@ -119,7 +119,7 @@ jobs: campaign: name: Qualify FPM accuracy (${{ inputs.artifact_key }}) needs: wheel - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 360 container: image: quay.io/pypa/manylinux_2_28_x86_64@sha256:4dc41da7df20400310c80d162a2fe2d2c2f3d9734d8dec20f6b9843711618deb diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index 225fe691d7..0dfb11bfba 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -292,12 +292,12 @@ jobs: matrix: arch: [amd64, arm64] python-version: ["3.11", "3.12", "3.13"] - runs-on: prod-aisimulate-default-${{ matrix.arch }}-v1 + runs-on: prod-aisim-default-${{ matrix.arch }}-v1 timeout-minutes: 15 container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: # Keep the license policy/tooling at the workflow revision. Older @@ -351,7 +351,7 @@ jobs: matrix: include: - arch: amd64 - runner: prod-aisimulate-default-amd64-v1 + runner: prod-aisim-default-amd64-v1 rust_target: x86_64-unknown-linux-gnu rustup_init_sha256: 4acc9acc76d5079515b46346a485974457b5a79893cfb01112423c89aeb5aa10 uv_target: x86_64-unknown-linux-gnu @@ -359,7 +359,7 @@ jobs: # quay.io/pypa/manylinux_2_28_x86_64:2026.08.24-1 container_image: quay.io/pypa/manylinux_2_28_x86_64@sha256:4dc41da7df20400310c80d162a2fe2d2c2f3d9734d8dec20f6b9843711618deb - arch: arm64 - runner: prod-aisimulate-default-arm64-v1 + runner: prod-aisim-default-arm64-v1 rust_target: aarch64-unknown-linux-gnu rustup_init_sha256: 9732d6c5e2a098d3521fca8145d826ae0aaa067ef2385ead08e6feac88fa5792 uv_target: aarch64-unknown-linux-gnu @@ -380,7 +380,7 @@ jobs: # for the runner's node24-based actions. image: ${{ matrix.container_image }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim defaults: run: shell: bash diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 1ad3e51217..1dc12ed878 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -53,7 +53,7 @@ jobs: needs: select if: needs.select.outputs.run_comparison == 'true' name: Forward Prediction Performance (advisory) - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 45 defaults: run: @@ -61,7 +61,7 @@ jobs: container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/prediction-regression-gate.yml b/.github/workflows/prediction-regression-gate.yml index f65a9b58be..bbe794cce4 100644 --- a/.github/workflows/prediction-regression-gate.yml +++ b/.github/workflows/prediction-regression-gate.yml @@ -56,7 +56,7 @@ jobs: collect: name: Collect prediction snapshot (${{ matrix.side }}) needs: refs - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 45 strategy: fail-fast: false @@ -65,7 +65,7 @@ jobs: container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - name: Checkout comparison revision diff --git a/.github/workflows/runner-canary.yml b/.github/workflows/runner-canary.yml new file mode 100644 index 0000000000..fa17cbbf64 --- /dev/null +++ b/.github/workflows/runner-canary.yml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# Keep normal producers paused until this smoke matrix passes. +name: Runner canary + +on: + workflow_dispatch: + push: + branches: ["pull-request/*"] + paths: [".github/workflows/runner-canary.yml"] + +permissions: + contents: read + +jobs: + canary: + if: github.repository == 'ai-dynamo/aisim' + name: Runner canary (${{ matrix.pool }}) + strategy: + fail-fast: false + matrix: + include: + - pool: amd64 + runner: prod-aisim-default-amd64-v1 + machine: x86_64 + scratch: true + - pool: arm64 + runner: prod-aisim-default-arm64-v1 + machine: aarch64 + scratch: true + runs-on: ${{ matrix.runner }} + timeout-minutes: 10 + container: + image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} + env: + HOME: /__w/aisim/aisim + USER: runner + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Verify source, job workspace, architecture and storage + shell: bash + env: + EXPECTED_MACHINE: ${{ matrix.machine }} + EXPECT_SCRATCH: ${{ matrix.scratch }} + run: | + set -euo pipefail + test "${GITHUB_REPOSITORY}" = ai-dynamo/aisim + test "$(git rev-parse HEAD)" = "${GITHUB_SHA}" + test "$(pwd -P)" = /__w/aisim/aisim + test "${HOME}" = /__w/aisim/aisim + test -w "${HOME}" + test "$(uname -m)" = "${EXPECTED_MACHINE}" + probe=$(mktemp "${HOME}/.runner-canary.XXXXXX") + rm "${probe}" + if [[ "${EXPECT_SCRATCH}" == true ]]; then + test -w /scratch + probe=$(mktemp /scratch/runner-canary.XXXXXX) + rm "${probe}" + fi + printf 'Verified source %s on %s (%s) with writable HOME=%s\n' "${GITHUB_SHA}" "${RUNNER_NAME}" "${EXPECTED_MACHINE}" "${HOME}" + + shared: + if: github.repository == 'ai-dynamo/aisim' + name: Runner canary (shared) + runs-on: dynamo-cpu-4gi-amd64 + timeout-minutes: 10 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Verify shared runner admission, source and writable workspace + shell: bash + run: | + set -euo pipefail + test "${GITHUB_REPOSITORY}" = ai-dynamo/aisim + test "$(git rev-parse HEAD)" = "${GITHUB_SHA}" + test "$(pwd -P)" = "$(realpath "${GITHUB_WORKSPACE}")" + test "$(uname -m)" = x86_64 + test -w "${HOME}" + probe=$(mktemp .runner-canary.XXXXXX) + rm "${probe}" + printf 'Verified source %s on shared runner %s\n' "${GITHUB_SHA}" "${RUNNER_NAME}" diff --git a/.github/workflows/simulation-performance.yml b/.github/workflows/simulation-performance.yml index 8ffe65a472..6b7ca3174b 100644 --- a/.github/workflows/simulation-performance.yml +++ b/.github/workflows/simulation-performance.yml @@ -165,7 +165,7 @@ jobs: needs: select if: needs.select.outputs.run_comparison == 'true' name: Build simulation wheel (${{ matrix.side }}) - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 30 strategy: fail-fast: false @@ -181,7 +181,7 @@ jobs: container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -260,7 +260,7 @@ jobs: needs: [select, build] if: needs.select.outputs.run_comparison == 'true' name: Simulation Performance (advisory) - runs-on: prod-aisimulate-default-amd64-v1 + runs-on: prod-aisim-default-amd64-v1 timeout-minutes: 75 defaults: run: @@ -268,7 +268,7 @@ jobs: container: image: ${{ vars.CI_JOB_CONTAINER_IMAGE }} env: - HOME: ${{ github.workspace }} + HOME: /__w/aisim/aisim USER: runner env: BASE_SHA: ${{ needs.select.outputs.base_sha }} diff --git a/docs/perf-model/configuration.md b/docs/perf-model/configuration.md index a4d4d1976e..229f58d000 100644 --- a/docs/perf-model/configuration.md +++ b/docs/perf-model/configuration.md @@ -1398,12 +1398,16 @@ work as before in this release. The next release removes them. | `engine.estimation_mode` | `auto` | `x` | `-` | Deprecated; use [`engine.ais_perf_model`](#unified-perf-model-input). `auto`, `op_level`, `fpm_interpolation`, `fpm_regression`, or `fpm_learned`. Regression and learned roles are priced per iteration (see [engine replay timing](#engine-replay-timing)). | | `engine.workers..timing.estimation_mode` | `null` | `x` | `-` | Deprecated; use [`engine.ais_perf_model`](#unified-perf-model-input). Optional role override using the same five modes; omission inherits the global selection. | | `engine.workers..timing.type` | `default` | `x` | `-` | `default`, `fixed`, or `polynomial`. | -| `engine.workers..timing.prefill_ms` | `null` | `x` | `-` | Nonnegative and required for `fixed` timing. | -| `engine.workers..timing.decode_ms` | `null` | `x` | `-` | Nonnegative and required for `fixed` timing. | +| `engine.workers..timing.prefill_ms` | `null` | `x` | `-` | Finite, nonnegative and required for `fixed` timing. | +| `engine.workers..timing.decode_ms` | `null` | `x` | `-` | Finite, nonnegative and required for `fixed` timing. | | `engine.workers..timing.forward_model` | `op_level` | `x` | `-` | Deprecated; use [`engine.ais_perf_model`](#unified-perf-model-input). `op_level` or `fpm`; `default` timing only. `fpm` replays whole-forward (FPM) latency measured for the role's exact model, hardware, backend version, parallel shape and quantization, and fails closed when no such cell exists. | | `engine.workers..timing.fpm_parquet_path` | `null` | `x` | `-` | Deprecated; use [`engine.ais_perf_model`](#unified-perf-model-input). External FPM parquet for `forward_model: fpm`; the adjacent same-stem `.metadata.json` sidecar is required. Relative paths are anchored to the working directory when the engine is constructed. Preserved per role in recommendations, candidate YAML, and ordinary prefill/decode companions of AFD roles. | | `engine.workers..timing.estimator_config.state_snapshot` | `null` | `x` | `-` | Deprecated; use [`engine.ais_perf_model`](#unified-perf-model-input). `recommend`: `{path, sha256}` of a calibrated snapshot; the role takes its estimator and engine identity from it. See [snapshot roles](#recommending-with-a-calibrated-snapshot). `predict` requires the complete saved configuration, as for any `state_snapshot`. | +Fixed timing accepts zero for either phase. Nonfinite values (infinity or NaN) +are configuration errors, rejected before prediction output is prepared, including +when `--overwrite` is used. + AFD replay prices every decode pass at its actual batch, context length and MTP verification width. The former `estimator_config.afd.frozen_decode_identity` control and saved pricing identity have been removed. Configurations and saved diff --git a/python/aisim/src/aisim/config/engine.py b/python/aisim/src/aisim/config/engine.py index cbae5529d0..0ccc942e1f 100644 --- a/python/aisim/src/aisim/config/engine.py +++ b/python/aisim/src/aisim/config/engine.py @@ -501,8 +501,8 @@ def _preserve_legacy_estimator_selection(cls, value): value.setdefault("fallback_policy", "deny") return value - prefill_ms: float | None = Field(default=None, ge=0.0) - decode_ms: float | None = Field(default=None, ge=0.0) + prefill_ms: float | None = Field(default=None, ge=0.0, allow_inf_nan=False) + decode_ms: float | None = Field(default=None, ge=0.0, allow_inf_nan=False) @model_validator(mode="after") def _validate_timing(self) -> TimingConfig: