Instructions to use KexuanShi/Megatron-LM with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use KexuanShi/Megatron-LM with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
| # Copyright (c) 2020-2021, NVIDIA CORPORATION. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: 'Release' | |
| defaults: | |
| run: | |
| shell: bash -x -e -u -o pipefail {0} | |
| on: | |
| workflow_call: | |
| inputs: | |
| release-ref: | |
| required: true | |
| description: Ref (SHA or branch) to release | |
| type: string | |
| dry-run: | |
| type: boolean | |
| required: true | |
| description: Do not publish a wheel and GitHub release. | |
| version-bump-branch: | |
| type: string | |
| required: true | |
| description: Branch to target for version bump | |
| create-gh-release: | |
| required: false | |
| description: Create a GitHub release | |
| type: boolean | |
| default: true | |
| secrets: | |
| TWINE_USERNAME: | |
| required: true | |
| TWINE_PASSWORD: | |
| required: true | |
| SLACK_WEBHOOK_ADMIN: | |
| required: true | |
| SLACK_WEBHOOK: | |
| required: true | |
| PAT: | |
| required: true | |
| permissions: | |
| contents: write # To read repository content | |
| pull-requests: write # To create PR(s) | |
| jobs: | |
| build-test-publish-wheels-dry-run: | |
| uses: ./.github/workflows/_build_test_publish_wheel.yml | |
| with: | |
| dry-run: true | |
| ref: ${{ inputs.release-ref }} | |
| no-publish: true | |
| secrets: | |
| TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} | |
| TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} | |
| bump-next-version: | |
| runs-on: ubuntu-latest | |
| environment: main # ${{ inputs.dry-run == true && 'public' || 'main' }} | |
| needs: build-test-publish-wheels-dry-run | |
| if: | | |
| ( | |
| success() || !failure() | |
| ) | |
| && !cancelled() | |
| outputs: | |
| release-version: ${{ steps.bump-version-mcore.outputs.release-version }} | |
| env: | |
| IS_DRY_RUN: ${{ inputs.dry-run }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| path: ${{ github.run_id }} | |
| token: ${{ secrets.PAT }} | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| ref: ${{ inputs.release-ref }} | |
| - name: Bump version MCore | |
| id: bump-version-mcore | |
| env: | |
| SRC_DIR: '' | |
| PYPROJECT_NAME: 'megatron.core' | |
| run: | | |
| set +u | |
| cd ${{ github.run_id }} | |
| PACKAGE_INFO_FILE="$SRC_DIR${PYPROJECT_NAME//.//}/package_info.py" | |
| MAJOR=$(cat $PACKAGE_INFO_FILE | awk '/^MAJOR = /' | awk -F"= " '{print $2}') | |
| MINOR=$(cat $PACKAGE_INFO_FILE | awk '/^MINOR = /' | awk -F"= " '{print $2}') | |
| PATCH=$(cat $PACKAGE_INFO_FILE | awk '/^PATCH = /' | awk -F"= " '{print $2}') | |
| PRERELEASE=$(cat $PACKAGE_INFO_FILE | awk '/^PRE_RELEASE = /' | awk -F"= " '{print $2}' | tr -d '"' | tr -d "'") | |
| echo "release-version=$MAJOR.$MINOR.$PATCH$PRERELEASE" | tee -a "$GITHUB_OUTPUT" | |
| if [[ "$PRERELEASE" != "" ]]; then | |
| if [[ "$PRERELEASE" == *rc* ]]; then | |
| NEXT_PATCH=$PATCH | |
| NEXT_PRERELEASE=rc$((${PRERELEASE#rc} + 1)) | |
| elif [[ "$PRERELEASE" == *a* ]]; then | |
| NEXT_PATCH=$PATCH | |
| NEXT_PRERELEASE=a$((${PRERELEASE#a} + 1)) | |
| else | |
| echo "Unknown pre-release: $PRERELEASE" | |
| exit 1 | |
| fi | |
| else | |
| NEXT_PATCH=$((${PATCH} + 1)) | |
| NEXT_PRERELEASE=$PRERELEASE | |
| fi | |
| sed -i "/^PATCH/c\PATCH = $NEXT_PATCH" $PACKAGE_INFO_FILE | |
| sed -i "/^PRE_RELEASE/c\PRE_RELEASE = \"$NEXT_PRERELEASE\"" $PACKAGE_INFO_FILE | |
| echo "version=$MAJOR.$MINOR.$NEXT_PATCH$NEXT_PRERELEASE" | tee -a "$GITHUB_OUTPUT" | |
| - name: Bump version MFSDP | |
| id: bump-version-mfsdp | |
| env: | |
| SRC_DIR: 'megatron/core/distributed/fsdp/src/' | |
| PYPROJECT_NAME: 'megatron_fsdp' | |
| run: | | |
| set +u | |
| cd ${{ github.run_id }} | |
| PACKAGE_INFO_FILE="$SRC_DIR${PYPROJECT_NAME//.//}/package_info.py" | |
| MAJOR=$(cat $PACKAGE_INFO_FILE | awk '/^MAJOR = /' | awk -F"= " '{print $2}') | |
| MINOR=$(cat $PACKAGE_INFO_FILE | awk '/^MINOR = /' | awk -F"= " '{print $2}') | |
| PATCH=$(cat $PACKAGE_INFO_FILE | awk '/^PATCH = /' | awk -F"= " '{print $2}') | |
| PRERELEASE=$(cat $PACKAGE_INFO_FILE | awk '/^PRE_RELEASE = /' | awk -F"= " '{print $2}' | tr -d '"' | tr -d "'") | |
| if [[ "$PRERELEASE" != "" ]]; then | |
| if [[ "$PRERELEASE" == *rc* ]]; then | |
| NEXT_PATCH=$PATCH | |
| NEXT_PRERELEASE=rc$((${PRERELEASE#rc} + 1)) | |
| elif [[ "$PRERELEASE" == *a* ]]; then | |
| NEXT_PATCH=$PATCH | |
| NEXT_PRERELEASE=a$((${PRERELEASE#a} + 1)) | |
| else | |
| echo "Unknown pre-release: $PRERELEASE" | |
| exit 1 | |
| fi | |
| else | |
| NEXT_PATCH=$((${PATCH} + 1)) | |
| NEXT_PRERELEASE=$PRERELEASE | |
| fi | |
| sed -i "/^PATCH/c\PATCH = $NEXT_PATCH" $PACKAGE_INFO_FILE | |
| sed -i "/^PRE_RELEASE/c\PRE_RELEASE = \"$NEXT_PRERELEASE\"" $PACKAGE_INFO_FILE | |
| echo "version=$MAJOR.$MINOR.$NEXT_PATCH$NEXT_PRERELEASE" | tee -a "$GITHUB_OUTPUT" | |
| - name: Create and push deployment branch | |
| env: | |
| GH_TOKEN: ${{ secrets.PAT }} | |
| run: | | |
| cd ${{ github.run_id }} | |
| TMP_BRANCH="deploy-release/$(uuidgen)" | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| git checkout -b "$TMP_BRANCH" | |
| git add -A . | |
| git commit -m "beep boop 🤖: Bumping versions" || echo "No changes to commit" | |
| git push -u origin "$TMP_BRANCH" | |
| echo "TMP_BRANCH=$TMP_BRANCH" | tee -a $GITHUB_ENV | |
| # Create PR to collect app based status checks that run on PRs only | |
| # (like DCO check) | |
| PR_URL=$(gh pr create \ | |
| --base ${{ inputs.version-bump-branch }} \ | |
| --head $TMP_BRANCH \ | |
| --title "beep boop 🤖: Bumping versions" \ | |
| --body "This is an automated PR to bump versions.") | |
| # Extract PR number from URL | |
| PR_NUMBER=$(echo $PR_URL | grep -o '[0-9]*$') | |
| # Add comment to the newly created PR | |
| echo gh pr comment $PR_NUMBER --body "/ok to test $(git rev-parse HEAD)" | |
| - name: Wait for status checks on tmp branch | |
| uses: actions/github-script@v7 | |
| id: wait-status | |
| with: | |
| github-token: ${{ secrets.PAT }} | |
| script: | | |
| const branch = process.env.TMP_BRANCH; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| // Get latest commit SHA of branch | |
| const { data: refData } = await github.rest.git.getRef({ | |
| owner, | |
| repo, | |
| ref: `heads/${branch}`, // note: no 'refs/' prefix here | |
| }); | |
| const sha = refData.object.sha; | |
| console.log(`Polling status for commit SHA: ${sha}`); | |
| let checksPassed = false; | |
| let maxAttempts = 30; | |
| let attempt = 0; | |
| const delay = ms => new Promise(res => setTimeout(res, ms)); | |
| while (!checksPassed && attempt < maxAttempts) { | |
| attempt++; | |
| // Use commit SHA instead of branch ref | |
| const { data: status } = await github.rest.repos.getCombinedStatusForRef({ | |
| owner, | |
| repo, | |
| ref: sha, | |
| }); | |
| const { data: checks } = await github.rest.checks.listForRef({ | |
| owner, | |
| repo, | |
| ref: sha, | |
| }); | |
| const allStatuses = status.statuses; | |
| const allChecks = checks.check_runs; | |
| if (allStatuses.length === 0 && allChecks.length === 0) { | |
| console.log(`Attempt ${attempt}: No checks or statuses yet. Waiting...`); | |
| await delay(10000); | |
| continue; | |
| } | |
| const statusesOk = allStatuses.every(s => s.state === 'success'); | |
| const checksOk = allChecks.every(c => c.status === 'completed'); | |
| if (statusesOk && checksOk) { | |
| console.log('✅ All checks passed.'); | |
| checksPassed = true; | |
| break | |
| } | |
| console.log(`Attempt ${attempt}: Checks not complete yet. Waiting...`); | |
| await delay(10000); | |
| } | |
| if (!checksPassed) { | |
| core.setFailed('❌ Status checks did not pass in time'); | |
| } | |
| - name: Merge into ${{ inputs.version-bump-branch }} | |
| run: | | |
| cd ${{ github.run_id }} | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| CMD=$(echo -E 'git push origin ${{ inputs.version-bump-branch }}') | |
| if [[ "$IS_DRY_RUN" == "true" ]]; then | |
| echo "dry-run enabled, would have run: $CMD" | |
| else | |
| # Here we account for potential race conditions from multiple concurrent releases. | |
| # Those can be legit (operating on different packages within the monorepo, for example) | |
| # but the pushes would be still rejected purely because of git's inability to | |
| # push non-fast-forward updates to the branch. In this case we would need to let | |
| # a retry. | |
| git fetch origin ${{ inputs.version-bump-branch }} | |
| git checkout ${{ inputs.version-bump-branch }} | |
| git merge ${{ env.TMP_BRANCH }} | |
| for attempt in {1..3}; do | |
| if eval "$CMD"; then | |
| echo "Git push succeeded on attempt $attempt" | |
| break | |
| else | |
| echo "Git push failed on attempt $attempt" | |
| if [[ $attempt -lt 3 ]]; then | |
| sleep $((RANDOM % 3 + 1)) | |
| # We refetch, reset and re-merge. Note resetting because the local | |
| # branch is "contaminated" with previous merge attempt. | |
| git fetch origin ${{ inputs.version-bump-branch }} | |
| git reset --hard origin/${{ inputs.version-bump-branch }} | |
| git merge ${{ env.TMP_BRANCH }} | |
| else | |
| echo "Git push failed after 3 attempts" | |
| exit 1 | |
| fi | |
| fi | |
| done | |
| fi | |
| - name: Delete ${{ env.TMP_BRANCH }} branch | |
| if: always() | |
| run: | | |
| cd ${{ github.run_id }} | |
| git push -d origin ${{ env.TMP_BRANCH }} | |
| build-test-publish-wheels: | |
| needs: [bump-next-version] | |
| uses: ./.github/workflows/_build_test_publish_wheel.yml | |
| with: | |
| dry-run: false | |
| ref: ${{ inputs.release-ref }} | |
| no-publish: false | |
| secrets: | |
| TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} | |
| TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} | |
| create-gh-release: | |
| needs: [build-test-publish-wheels, bump-next-version] | |
| runs-on: ubuntu-latest | |
| environment: ${{ inputs.dry-run == true && 'public' || 'main' }} | |
| if: | | |
| ( | |
| success() || !failure() | |
| ) | |
| && inputs.create-gh-release == true | |
| && !cancelled() | |
| outputs: | |
| is-release-candidate: ${{ steps.version-number.outputs.is-release-candidate }} | |
| env: | |
| REPOSITORY: ${{ github.repository }} | |
| PROJECT_NAME: Megatron Core | |
| VERSION: ${{ needs.bump-next-version.outputs.release-version }} | |
| TAG_PREFIX: ${{ inputs.gh-release-tag-prefix || '' }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| path: ${{ github.run_id }} | |
| ref: ${{ inputs.release-ref }} | |
| token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} | |
| - name: Create release | |
| id: version-number | |
| env: | |
| SHA: ${{ inputs.release-ref }} | |
| GH_TOKEN: ${{ secrets.PAT }} | |
| IS_DRY_RUN: ${{ inputs.dry-run }} | |
| run: | | |
| cd ${{ github.run_id }} | |
| IS_RELEASE_CANDIDATE=$([[ "$VERSION" == *rc* ]] && echo "true" || echo "false") | |
| IS_ALPHA=$([[ "$VERSION" == *a* ]] && echo "true" || echo "false") | |
| IS_PRERELEASE=$([[ "$IS_RELEASE_CANDIDATE" == "true" || "$IS_ALPHA" == "true" ]] && echo "true" || echo "false") | |
| NAME="NVIDIA $PROJECT_NAME ${VERSION}" | |
| if [[ "$IS_RELEASE_CANDIDATE" == "true" ]]; then | |
| DATE=$(date +"%Y-%m-%d") | |
| CHANGELOG="Prerelease: $NAME ($DATE)" | |
| else | |
| CHANGELOG=$(awk '/^## '"$NAME"'/{flag=1; next} /^## /{flag=0} flag' CHANGELOG.md) | |
| CHANGELOG=$(echo "$CHANGELOG" | sed '/./,$!d' | sed ':a;N;$!ba;s/\n$//') | |
| fi | |
| echo "is-release-candidate=$IS_RELEASE_CANDIDATE" | tee -a "$GITHUB_OUTPUT" | |
| PAYLOAD=$(jq -nc \ | |
| --arg TAG_NAME "${TAG_PREFIX}v${VERSION}" \ | |
| --arg CI_COMMIT_BRANCH "$SHA" \ | |
| --arg NAME "$NAME" \ | |
| --arg BODY "$CHANGELOG" \ | |
| --argjson PRERELEASE "$IS_PRERELEASE" \ | |
| '{ | |
| "tag_name": $TAG_NAME, | |
| "target_commitish": $CI_COMMIT_BRANCH, | |
| "name": $NAME, | |
| "body": $BODY, | |
| "draft": false, | |
| "prerelease": $PRERELEASE, | |
| "generate_release_notes": false | |
| }' | |
| ) | |
| echo -E "$PAYLOAD" > payload.txt | |
| CMD=$(echo -E 'curl -L \ | |
| -X POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "Authorization: Bearer '"$GH_TOKEN"'" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| https://api.github.com/repos/'"$REPOSITORY"'/releases \ | |
| -d @payload.txt | |
| ') | |
| if [[ "$IS_DRY_RUN" == "true" ]]; then | |
| echo -E "$CMD" | |
| else | |
| eval "$CMD" | |
| fi | |
| notify: | |
| needs: [build-test-publish-wheels, create-gh-release] | |
| runs-on: ubuntu-latest | |
| environment: ${{ inputs.dry-run == true && 'public' || 'main' }} | |
| env: | |
| GH_URL: https://github.com/${{ github.repository }}/releases/tag/v${{ needs.build-test-publish-wheels.outputs.version }} | |
| PYPI_URL: https://${{ inputs.dry-run == true && 'test.' || '' }}pypi.org/project/${{ needs.build-test-publish-wheels.outputs.pypi-name }}/${{ needs.build-test-publish-wheels.outputs.version }}/ | |
| PROJECT_NAME: Megatron Core | |
| VERSION: ${{ needs.build-test-publish-wheels.outputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: NVIDIA-NeMo/FW-CI-templates | |
| ref: v0.17.0 | |
| path: send-slack-alert | |
| - name: Send Slack alert | |
| uses: ./send-slack-alert/.github/actions/send-slack-alert | |
| env: | |
| MESSAGE: | | |
| ${{ inputs.dry-run == true && 'This is a dry-run, nothing actually happened: ' || '' }}We have released `${{ env.VERSION }}` of `NVIDIA ${{ env.PROJECT_NAME }}` 🚀✨🎉 | |
| • <${{ env.GH_URL }}|GitHub release> | |
| • <${{ env.PYPI_URL }}|PyPi release> | |
| with: | |
| message: ${{ env.MESSAGE }} | |
| webhook: ${{ secrets.SLACK_WEBHOOK }} | |