Skip to content

Commit f376431

Browse files
Merge branch 'main' into khazic/feat/dspark-core
2 parents c8cf0bc + 2b8cb21 commit f376431

507 files changed

Lines changed: 19373 additions & 3560 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.dev.commit‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
af91b6b5cc5aec01458b8e6d24ccb0f4717e49e3
1+
12eed0a5ac3f1ced6a3a4f76727db530bdbf7391

‎.github/CODEOWNERS‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ pyproject.toml @nvidia-nemo/automation
55
ruff.toml @nvidia-nemo/automation
66
.pre-commit-config.yaml
77

8-
scripts/performance/argument_parser.py @nvidia-nemo/automation @malay-nagda @erhoo82
9-
scripts/performance/setup_experiment.py @nvidia-nemo/automation @malay-nagda @erhoo82
10-
scripts/performance/bootstrap.py @nvidia-nemo/automation @malay-nagda @erhoo82
11-
scripts/performance/run_script.py @nvidia-nemo/automation @malay-nagda @erhoo82
12-
scripts/performance/run_recipe.py @nvidia-nemo/automation @malay-nagda @erhoo82
8+
scripts/performance @malay-nagda @dingqingy-nv
9+
src/megatron/bridge/perf_recipes @malay-nagda @dingqingy-nv
10+
11+
scripts/performance/argument_parser.py @nvidia-nemo/automation
12+
scripts/performance/setup_experiment.py @nvidia-nemo/automation
13+
scripts/performance/bootstrap.py @nvidia-nemo/automation
14+
scripts/performance/run_script.py @nvidia-nemo/automation
15+
scripts/performance/run_recipe.py @nvidia-nemo/automation

‎.github/actions/test-template/action.yml‎

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ inputs:
4343
description: "Has Azure credentials"
4444
required: false
4545
default: "false"
46-
PAT:
47-
description: "GitHub Personal Access Token"
46+
github-token:
47+
description: "GitHub token"
4848
required: true
4949
container-image:
5050
description: "Container image to use for test"
@@ -59,6 +59,14 @@ inputs:
5959
runner:
6060
description: "Runner to use for test"
6161
required: true
62+
shard-id:
63+
description: "Zero-based pytest shard index"
64+
required: false
65+
default: ""
66+
num-shards:
67+
description: "Total number of pytest shards"
68+
required: false
69+
default: ""
6270

6371
runs:
6472
using: "composite"
@@ -114,9 +122,14 @@ runs:
114122
echo "::group::Start test container"
115123
if [[ "$MOUNT_FS" == "true" ]]; then
116124
VOLUME_ARGS="--volume ${{ inputs.test-data-path }}:/home/TestData --env HF_HUB_OFFLINE=1"
125+
HF_HOME=/home/TestData/HF_HOME
126+
NEMO_HOME=/home/TestData/nemo_home
117127
else
118128
VOLUME_ARGS=""
129+
HF_HOME=/home/ubuntu/.cache/huggingface
130+
NEMO_HOME=/home/ubuntu/.cache/nemo
119131
fi
132+
HF_MODULES_CACHE=/home/ubuntu/.cache/huggingface/modules
120133
121134
cmd=$(cat <<RUN_TEST_EOF
122135
#!/bin/bash
@@ -131,10 +144,13 @@ runs:
131144
--cpus=40 \
132145
--env GHA_RUNNER=${{ inputs.runner }} \
133146
--env HYDRA_FULL_ERROR=1 \
134-
--env HF_HOME=/home/TestData/HF_HOME \
135-
--env NEMO_HOME=/home/TestData/nemo_home \
147+
--env HF_HOME=$HF_HOME \
148+
--env HF_MODULES_CACHE=$HF_MODULES_CACHE \
149+
--env NEMO_HOME=$NEMO_HOME \
136150
--env RUN_ID=${{ github.run_id }} \
137151
--env UV_NO_SYNC=1 \
152+
--env SHARD_ID=${{ inputs.shard-id }} \
153+
--env NUM_SHARDS=${{ inputs.num-shards }} \
138154
--workdir /opt/Megatron-Bridge \
139155
$VOLUME_ARGS \
140156
${{ inputs.container-image }} \
@@ -159,7 +175,7 @@ runs:
159175
160176
docker exec -t nemo_container_${{ github.run_id }} bash -c '
161177
set -e
162-
export GH_TOKEN=${{ inputs.PAT }}
178+
export GH_TOKEN=${{ inputs.github-token }}
163179
164180
timeout $(( ${{ inputs.timeout }} * 60 ))s bash tests/${{ inputs.is_unit_test == 'true' && 'unit_tests' || format('functional_tests/launch_scripts/{0}', inputs.script_dir) }}/${{ inputs.script }}.sh || EXIT_CODE=$?
165181

‎.github/scripts/test_docker_dependency_layers.sh‎

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set -euo pipefail
33

44
dockerfile="${1:-docker/Dockerfile.ci}"
55
workflow="${2:-.github/workflows/cicd-main.yml}"
6+
fw_final_dockerfile="${3:-docker/Dockerfile.fw_final}"
67

78
baseline_arg_line=$(grep -n '^ARG BASELINE_MCORE_REF$' "$dockerfile" | cut -d: -f1)
89
baseline_clone_line=$(grep -n 'git clone --filter=blob:none --no-checkout' "$dockerfile" | cut -d: -f1)
@@ -24,14 +25,23 @@ trap 'rm -rf "$temporary_dir"' EXIT
2425
((baseline_line < dispatched_copy_line))
2526
((dispatched_copy_line < delta_line))
2627

28+
fw_final_from_line=$(grep -n '^FROM ${NEMO_FW_FINAL_BASE_IMAGE} AS nemo_fw_final$' "$fw_final_dockerfile" | cut -d: -f1)
29+
fw_final_root_line=$(grep -n '^USER root$' "$fw_final_dockerfile" | cut -d: -f1)
30+
fw_final_clone_line=$(grep -n '^RUN git clone --depth 1 https://github.com/NVIDIA-NeMo/NeMo.git' "$fw_final_dockerfile" | cut -d: -f1)
31+
[[ -n "$fw_final_from_line" ]]
32+
[[ -n "$fw_final_root_line" ]]
33+
[[ -n "$fw_final_clone_line" ]]
34+
((fw_final_from_line < fw_final_root_line))
35+
((fw_final_root_line < fw_final_clone_line))
36+
2737
grep -q -- '--mount=type=cache,target=/root/.cache/uv' "$dockerfile"
2838
if grep -q -- '--mount=type=secret,id=GH_TOKEN' "$dockerfile"; then
2939
echo "Baseline MCore clone must not require a GitHub token" >&2
3040
exit 1
3141
fi
3242
mcore_reinstall_line=$(grep -n 'uv pip install --no-deps --reinstall -e 3rdparty/Megatron-LM' "$dockerfile" | cut -d: -f1)
3343
helper_assertion_line=$(grep -n "find 3rdparty/Megatron-LM/megatron/core/datasets -maxdepth 1 -name 'helpers_cpp\*\.so'" "$dockerfile" | cut -d: -f1)
34-
final_copy_line=$(grep -n '^COPY --chmod=644 \. /opt/Megatron-Bridge$' "$dockerfile" | cut -d: -f1)
44+
final_copy_line=$(grep -nE '^COPY (--chmod=644|--chown=1000:1000) \. /opt/Megatron-Bridge$' "$dockerfile" | cut -d: -f1)
3545
[[ -n "$mcore_reinstall_line" ]]
3646
[[ -n "$helper_assertion_line" ]]
3747
[[ -n "$final_copy_line" ]]
@@ -52,7 +62,7 @@ if grep -q 'MCORE_REF="${{ github.event.inputs.mcore_ref }}"' "$workflow"; then
5262
echo "Dispatch inputs must enter shell steps through env" >&2
5363
exit 1
5464
fi
55-
test "$(grep -c 'validate_mcore_revision.sh "$MCORE_REPO" "$MCORE_REF"' "$workflow")" = 2
65+
test "$(grep -c 'validate_mcore_revision.sh "$MCORE_REPO" "$MCORE_REF" "$TRIGGERED_BY"' "$workflow")" = 2
5666
test "$(grep -c 'git fetch "$MCORE_REPO" "$MCORE_REF"' "$workflow")" = 2
5767
test "$(grep -c 'git checkout "$MCORE_REF"' "$workflow")" = 2
5868
test "$(grep -c 'test "$(git rev-parse HEAD)" = "$MCORE_REF"' "$workflow")" = 1
@@ -99,6 +109,13 @@ ancestor_sha=$(git -C "$revision_worktree" rev-parse HEAD)
99109
printf 'main\n' >>"$revision_worktree/file"
100110
git -C "$revision_worktree" commit -qam main
101111
main_sha=$(git -C "$revision_worktree" rev-parse HEAD)
112+
git -C "$revision_worktree" switch -q -c dev
113+
printf 'dev\n' >>"$revision_worktree/file"
114+
git -C "$revision_worktree" commit -qam dev
115+
dev_ancestor_sha=$(git -C "$revision_worktree" rev-parse HEAD)
116+
printf 'dev tip\n' >>"$revision_worktree/file"
117+
git -C "$revision_worktree" commit -qam dev-tip
118+
dev_sha=$(git -C "$revision_worktree" rev-parse HEAD)
102119
git -C "$revision_worktree" branch contributor "$ancestor_sha"
103120
git -C "$revision_worktree" switch -q contributor
104121
printf 'approved\n' >>"$revision_worktree/file"
@@ -122,6 +139,7 @@ git -C "$revision_worktree" add unapproved
122139
git -C "$revision_worktree" commit -q -m unapproved
123140
unapproved_sha=$(git -C "$revision_worktree" rev-parse HEAD)
124141
git -C "$revision_worktree" push -q "$revision_repo" "$main_sha:refs/heads/main"
142+
git -C "$revision_worktree" push -q "$revision_repo" "$dev_sha:refs/heads/dev"
125143
git -C "$revision_worktree" push -q "$revision_repo" "$mirror_sha:refs/heads/pull-request/123"
126144
git -C "$revision_worktree" push -q "$revision_repo" "$merge_sha:refs/pull/123/merge"
127145
git -C "$revision_worktree" push -q \
@@ -140,9 +158,69 @@ sed "s#\.github/scripts/validate_mcore_repo\.sh#$temporary_dir/revision-bin/repo
140158
"$revision_validator" >"$temporary_dir/revision-validator"
141159
chmod +x "$temporary_dir/revision-validator"
142160
"$temporary_dir/revision-validator" "$revision_repo" "$ancestor_sha"
161+
"$temporary_dir/revision-validator" "$revision_repo" "$dev_ancestor_sha"
162+
"$temporary_dir/revision-validator" "$revision_repo" "$dev_sha"
143163
"$temporary_dir/revision-validator" "$revision_repo" "$mirror_sha"
144164
"$temporary_dir/revision-validator" "$revision_repo" "$merge_sha"
145165
"$temporary_dir/revision-validator" "$revision_repo" "$queue_sha"
166+
git -C "$revision_worktree" push -q \
167+
"$revision_repo" \
168+
":refs/heads/gh-readonly-queue/main/pr-123-$main_sha"
169+
if "$temporary_dir/revision-validator" "$revision_repo" "$queue_sha"; then
170+
echo "MCore revision validation accepted a deleted queue ref without source-run evidence" >&2
171+
exit 1
172+
fi
173+
cat >"$temporary_dir/revision-bin/gh" <<'EOF'
174+
#!/usr/bin/env bash
175+
[[ "$1" == "api" && "$2" == "repos/NVIDIA/Megatron-LM/actions/runs/$TEST_RUN_ID" ]] || exit 1
176+
printf '%s\t%s\t%s\t%s\n' \
177+
"${RUN_REPO:-NVIDIA/Megatron-LM}" \
178+
"${RUN_EVENT:-merge_group}" \
179+
"${RUN_SHA:-}" \
180+
"${RUN_BRANCH:-gh-readonly-queue/main/pr-123-0000000000000000000000000000000000000000}"
181+
EOF
182+
chmod +x "$temporary_dir/revision-bin/gh"
183+
TEST_RUN_ID=123456
184+
trigger_url="https://github.com/NVIDIA/Megatron-LM/actions/runs/$TEST_RUN_ID"
185+
PATH="$temporary_dir/revision-bin:$PATH" \
186+
TEST_RUN_ID="$TEST_RUN_ID" \
187+
RUN_SHA="$queue_sha" \
188+
RUN_BRANCH="gh-readonly-queue/main/pr-123-$main_sha" \
189+
"$temporary_dir/revision-validator" "$revision_repo" "$queue_sha" "$trigger_url"
190+
if PATH="$temporary_dir/revision-bin:$PATH" \
191+
TEST_RUN_ID="$TEST_RUN_ID" \
192+
RUN_SHA="$unapproved_sha" \
193+
RUN_BRANCH="gh-readonly-queue/main/pr-123-$main_sha" \
194+
"$temporary_dir/revision-validator" "$revision_repo" "$queue_sha" "$trigger_url"; then
195+
echo "MCore revision validation accepted source-run metadata for a different SHA" >&2
196+
exit 1
197+
fi
198+
if PATH="$temporary_dir/revision-bin:$PATH" \
199+
TEST_RUN_ID="$TEST_RUN_ID" \
200+
RUN_SHA="$queue_sha" \
201+
RUN_BRANCH="pull-request/123" \
202+
"$temporary_dir/revision-validator" "$revision_repo" "$queue_sha" "$trigger_url"; then
203+
echo "MCore revision validation accepted a non-queue source run" >&2
204+
exit 1
205+
fi
206+
if PATH="$temporary_dir/revision-bin:$PATH" \
207+
TEST_RUN_ID="$TEST_RUN_ID" \
208+
RUN_REPO="example/Megatron-LM" \
209+
RUN_SHA="$queue_sha" \
210+
RUN_BRANCH="gh-readonly-queue/main/pr-123-$main_sha" \
211+
"$temporary_dir/revision-validator" "$revision_repo" "$queue_sha" "$trigger_url"; then
212+
echo "MCore revision validation accepted an untrusted source-run repository" >&2
213+
exit 1
214+
fi
215+
if PATH="$temporary_dir/revision-bin:$PATH" \
216+
TEST_RUN_ID="$TEST_RUN_ID" \
217+
RUN_EVENT="push" \
218+
RUN_SHA="$queue_sha" \
219+
RUN_BRANCH="gh-readonly-queue/main/pr-123-$main_sha" \
220+
"$temporary_dir/revision-validator" "$revision_repo" "$queue_sha" "$trigger_url"; then
221+
echo "MCore revision validation accepted a non-merge-group source run" >&2
222+
exit 1
223+
fi
146224
if "$temporary_dir/revision-validator" "$revision_repo" "$queue_sha"x; then
147225
echo "MCore revision validation accepted a malformed queue SHA" >&2
148226
exit 1
@@ -164,11 +242,54 @@ if "$temporary_dir/revision-validator" "$revision_repo" not-a-full-sha; then
164242
exit 1
165243
fi
166244

245+
if ! grep -A1 '^te = \[$' pyproject.toml | grep -Fxq ' "megatron-core[te]",'; then
246+
echo "Bridge's TE extra must enable the selected MCore ref's TE extra" >&2
247+
exit 1
248+
fi
249+
grep -Fq '{ name = "megatron-core", extra = ["te"] }' uv.lock
250+
if grep -q 'transformer-engine @ git+https://github.com/NVIDIA/TransformerEngine.git@' pyproject.toml || \
251+
grep -q '^name = "transformer-engine"$' pyproject.toml; then
252+
echo "Bridge must inherit the TransformerEngine source and metadata from the selected MCore ref" >&2
253+
exit 1
254+
fi
255+
256+
lock_package_field() {
257+
local lock_file="$1"
258+
local package="$2"
259+
local field="$3"
260+
261+
awk -v package="$package" -v field="$field" '
262+
$0 == "[[package]]" { in_package = 1; package_matches = 0; next }
263+
in_package && $0 ~ /^\[\[/ { in_package = 0; package_matches = 0 }
264+
in_package && $0 == "name = \"" package "\"" { package_matches = 1; next }
265+
package_matches && index($0, field " = ") == 1 { print; exit }
266+
' "$lock_file"
267+
}
268+
269+
mlm_te_source=$(lock_package_field 3rdparty/Megatron-LM/uv.lock transformer-engine source)
270+
bridge_te_source=$(lock_package_field uv.lock transformer-engine source)
271+
if [[ ! "$mlm_te_source" =~ ^source\ =\ \{\ git\ =\ \"https://github.com/NVIDIA/TransformerEngine\.git\?rev=[0-9a-f]{40}#[0-9a-f]{40}\"\ \}$ ]]; then
272+
echo "Selected MCore lock must pin TransformerEngine to a full source revision" >&2
273+
exit 1
274+
fi
275+
if [[ "$bridge_te_source" != "$mlm_te_source" ]]; then
276+
echo "Bridge must lock the TransformerEngine source selected by MCore" >&2
277+
exit 1
278+
fi
279+
167280
composite_action=".github/actions/test-template/action.yml"
168281
if grep -qE 'mcore_(commit|ref)|MCORE_COMMIT|uv sync --all-extras --all-groups' "$composite_action"; then
169282
echo "Test template must use the already-validated MCore in the built image" >&2
170283
exit 1
171284
fi
285+
grep -Fq 'VOLUME_ARGS="--volume ${{ inputs.test-data-path }}:/home/TestData --env HF_HUB_OFFLINE=1"' "$composite_action"
286+
grep -q 'MOUNT_FS: ${{ inputs.is_unit_test == '\''false'\'' }}' "$composite_action"
287+
grep -q 'HF_HOME=/home/TestData/HF_HOME' "$composite_action"
288+
grep -q 'NEMO_HOME=/home/TestData/nemo_home' "$composite_action"
289+
grep -q 'HF_HOME=/home/ubuntu/.cache/huggingface' "$composite_action"
290+
grep -q 'NEMO_HOME=/home/ubuntu/.cache/nemo' "$composite_action"
291+
grep -q 'HF_MODULES_CACHE=/home/ubuntu/.cache/huggingface/modules' "$composite_action"
292+
grep -q -- '--env HF_MODULES_CACHE=\$HF_MODULES_CACHE' "$composite_action"
172293

173294
# The baseline dependency layer must be structurally independent of the mutable
174295
# dispatched checkout. CI validates the ordering statically so this regression
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
workflow="${1:-.github/workflows/cicd-main.yml}"
5+
6+
awk '
7+
function check_job() {
8+
if (!in_queue_chain || !has_success) {
9+
return
10+
}
11+
12+
checked++
13+
if (!allows_queue_bypass) {
14+
print job " uses success() but does not allow the intentional queue skip" > "/dev/stderr"
15+
failed = 1
16+
}
17+
}
18+
19+
/^ [[:alnum:]_-]+:$/ {
20+
check_job()
21+
job = $1
22+
sub(/:$/, "", job)
23+
in_queue_chain = (in_queue_chain || job == "cicd-compute-build-matrix")
24+
if (job == "Nemo_CICD_Test") {
25+
in_queue_chain = 0
26+
}
27+
has_success = 0
28+
allows_queue_bypass = 0
29+
next
30+
}
31+
32+
in_queue_chain && /success\(\)/ {
33+
has_success = 1
34+
}
35+
36+
in_queue_chain && /needs\.configure\.outputs\.skip_queue == '\''true'\'' && !failure\(\)/ {
37+
allows_queue_bypass = 1
38+
}
39+
40+
END {
41+
check_job()
42+
if (checked == 0) {
43+
print "No queue-dependent success() conditions found" > "/dev/stderr"
44+
exit 1
45+
}
46+
exit failed
47+
}
48+
' "$workflow"

‎.github/scripts/validate_mcore_revision.sh‎

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set -euo pipefail
33

44
repo="${1:-}"
55
revision="${2:-}"
6+
triggered_by="${3:-}"
67

78
if ! .github/scripts/validate_mcore_repo.sh "$repo"; then
89
exit 1
@@ -14,27 +15,32 @@ fi
1415
refs=$(git ls-remote \
1516
"$repo" \
1617
"refs/heads/main" \
18+
"refs/heads/dev" \
1719
"refs/heads/pull-request/*" \
18-
"refs/heads/gh-readonly-queue/main/pr-*" \
20+
"refs/heads/gh-readonly-queue/*/pr-*" \
1921
"refs/pull/*/merge")
2022
object_store=$(mktemp -d)
2123
trap 'rm -rf "$object_store"' EXIT
2224
git -C "$object_store" init --quiet
2325

2426
main_sha=$(awk '$2 == "refs/heads/main" {print $1}' <<<"$refs")
25-
if [[ -n "$main_sha" ]] && \
26-
git -C "$object_store" fetch --quiet --filter=blob:none --no-tags "$repo" "$main_sha" "$revision"; then
27-
if git -C "$object_store" merge-base --is-ancestor "$revision" "$main_sha"; then
28-
exit 0
27+
dev_sha=$(awk '$2 == "refs/heads/dev" {print $1}' <<<"$refs")
28+
for protected_sha in "$main_sha" "$dev_sha"; do
29+
if [[ -n "$protected_sha" ]] && \
30+
git -C "$object_store" fetch --quiet --filter=blob:none --no-tags "$repo" "$protected_sha" "$revision"; then
31+
if git -C "$object_store" merge-base --is-ancestor "$revision" "$protected_sha"; then
32+
exit 0
33+
fi
2934
fi
30-
fi
35+
done
3136

3237
while IFS=$'\t' read -r sha ref; do
3338
if [[ "$sha" != "$revision" ]]; then
3439
continue
3540
fi
36-
if [[ "$ref" =~ ^refs/heads/pull-request/[0-9]+$ ]] || \
37-
[[ "$ref" =~ ^refs/heads/gh-readonly-queue/main/pr-[0-9]+-[0-9a-f]{40}$ ]]; then
41+
if [[ "$ref" == "refs/heads/dev" ]] || \
42+
[[ "$ref" =~ ^refs/heads/pull-request/[0-9]+$ ]] || \
43+
[[ "$ref" =~ ^refs/heads/gh-readonly-queue/(main|dev)/pr-[0-9]+-[0-9a-f]{40}$ ]]; then
3844
exit 0
3945
fi
4046
done <<<"$refs"
@@ -53,4 +59,22 @@ while IFS=$'\t' read -r merge_sha merge_ref; do
5359
fi
5460
done <<<"$refs"
5561

62+
# GitHub deletes merge-queue refs when a group leaves the queue, which can
63+
# happen before MCore's remotely triggered MBridge run starts. In that case,
64+
# authenticate the immutable source run and require it to describe this exact
65+
# official merge-group SHA. Arbitrary workflow-dispatch inputs and fork SHAs
66+
# remain rejected.
67+
if [[ "$triggered_by" =~ ^https://github.com/NVIDIA/Megatron-LM/actions/runs/([1-9][0-9]*)$ ]]; then
68+
run_id="${BASH_REMATCH[1]}"
69+
run_metadata=$(gh api "repos/NVIDIA/Megatron-LM/actions/runs/$run_id" --jq \
70+
'[.repository.full_name, .event, .head_sha, .head_branch] | @tsv' 2>/dev/null) || run_metadata=""
71+
IFS=$'\t' read -r run_repo run_event run_sha run_branch <<<"$run_metadata"
72+
if [[ "$run_repo" == "NVIDIA/Megatron-LM" && \
73+
"$run_event" == "merge_group" && \
74+
"$run_sha" == "$revision" && \
75+
"$run_branch" =~ ^gh-readonly-queue/(main|dev)/pr-[0-9]+-[0-9a-f]{40}$ ]]; then
76+
exit 0
77+
fi
78+
fi
79+
5680
exit 1

0 commit comments

Comments
 (0)