hiyouga/LlamaFactory

7 workflows · maturity 67% · 4 patterns · GitHub ↗

Security 3.57/100

Practices

✓ Matrix✓ Permissions○ Security scan○ AI review✓ Cache✓ Concurrency○ Reusable workflows

Detected patterns

Security dimensions

permissions
3.6
security scan
0
supply chain
0
secret handling
0
harden runner
0

Workflows (7)

docker matrix .github/workflows/docker.yml
Triggers
workflow_dispatch, push, pull_request, release
Runs on
ubuntu-latest
Jobs
build
Matrix
include, include.device→ cuda, npu-a2, npu-a3
Actions
jlumbroso/free-disk-space, docker/setup-buildx-action, docker/login-action, docker/login-action, docker/build-push-action, docker/build-push-action, docker/build-push-action
Commands
  • if [ "${{ github.event_name }}" = "release" ]; then echo "tag=$(grep -oP 'VERSION = "\K[^"]+' src/llamafactory/extras/env.py)" >> "$GITHUB_OUTPUT" else echo "tag=latest" >> "$GITHUB_OUTPUT" fi
View raw YAML
name: docker

on:
  workflow_dispatch:
  push:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "docker/**"
      - ".github/workflows/*.yml"
  pull_request:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "docker/**"
      - ".github/workflows/*.yml"
  release:
    types:
      - published

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - device: "cuda"
          - device: "npu-a2"
          - device: "npu-a3"

    runs-on: ubuntu-latest

    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.device }}
      cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

    environment:
      name: docker
      url: https://hub.docker.com/r/hiyouga/llamafactory

    steps:
      - name: Free up disk space
        uses: jlumbroso/free-disk-space@v1.3.1
        with:
          tool-cache: true
          docker-images: false

      - name: Checkout
        uses: actions/checkout@v6

      - name: Get llamafactory version
        id: version
        run: |
          if [ "${{ github.event_name }}" = "release" ]; then
            echo "tag=$(grep -oP 'VERSION = "\K[^"]+' src/llamafactory/extras/env.py)" >> "$GITHUB_OUTPUT"
          else
            echo "tag=latest" >> "$GITHUB_OUTPUT"
          fi

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        if: ${{ github.event_name != 'pull_request' }}
        uses: docker/login-action@v3
        with:
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to Quay
        if: ${{ github.event_name != 'pull_request' && startsWith(matrix.device, 'npu') }}
        uses: docker/login-action@v3
        with:
          registry: quay.io
          username: ${{ vars.QUAY_ASCEND_USERNAME }}
          password: ${{ secrets.QUAY_ASCEND_TOKEN }}

      - name: Build and push Docker image (CUDA)
        if: ${{ matrix.device == 'cuda' }}
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./docker/docker-cuda/Dockerfile
          push: ${{ github.event_name != 'pull_request' }}
          tags: |
            docker.io/hiyouga/llamafactory:${{ steps.version.outputs.tag }}

      - name: Build and push Docker image (NPU-A2)
        if: ${{ matrix.device == 'npu-a2' }}
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          file: ./docker/docker-npu/Dockerfile
          push: ${{ github.event_name != 'pull_request' }}
          tags: |
            docker.io/hiyouga/llamafactory:${{ steps.version.outputs.tag }}-npu-a2
            quay.io/ascend/llamafactory:${{ steps.version.outputs.tag }}-npu-a2

      - name: Build and push Docker image (NPU-A3)
        if: ${{ matrix.device == 'npu-a3' }}
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          file: ./docker/docker-npu/Dockerfile
          build-args: |
            BASE_IMAGE=quay.io/ascend/cann:8.3.rc2-a3-ubuntu22.04-py3.11
          push: ${{ github.event_name != 'pull_request' }}
          tags: |
            docker.io/hiyouga/llamafactory:${{ steps.version.outputs.tag }}-npu-a3
            quay.io/ascend/llamafactory:${{ steps.version.outputs.tag }}-npu-a3
docs perms .github/workflows/docs.yml
Triggers
push, pull_request, workflow_dispatch
Runs on
ubuntu-latest, ubuntu-latest
Jobs
build, deploy
Actions
actions/configure-pages, actions/upload-pages-artifact, actions/deploy-pages
Commands
  • pip install -r docs/requirements.txt
  • sphinx-build -b html docs/zh docs/_build/html/zh sphinx-build -b html docs/en docs/_build/html/en printf '%s\n' \ '<!DOCTYPE html>' \ '<html>' \ ' <head>' \ ' <meta charset="utf-8" />' \ ' <meta http-equiv="refresh" content="0; url=zh/index.html" />' \ ' <script>window.location.href="zh/index.html"+window.location.search+window.location.hash;</script>' \ ' <title>Redirecting...</title>' \ ' </head>' \ ' <body>' \ ' <a href="zh/index.html">Redirecting...</a>' \ ' </body>' \ '</html>' \ > docs/_build/html/index.html touch docs/_build/html/.nojekyll
View raw YAML
name: Build and Deploy Sphinx Docs

on:
  push:
    branches: ["main"]
    paths:
      - "docs/**"
  pull_request:
    branches: ["main"]
    paths:
      - "docs/**"
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'

      - name: Install dependencies
        run: |
          pip install -r docs/requirements.txt

      - name: Build Sphinx
        run: |
          sphinx-build -b html docs/zh docs/_build/html/zh
          sphinx-build -b html docs/en docs/_build/html/en

          printf '%s\n' \
            '<!DOCTYPE html>' \
            '<html>' \
            '  <head>' \
            '    <meta charset="utf-8" />' \
            '    <meta http-equiv="refresh" content="0; url=zh/index.html" />' \
            '    <script>window.location.href="zh/index.html"+window.location.search+window.location.hash;</script>' \
            '    <title>Redirecting...</title>' \
            '  </head>' \
            '  <body>' \
            '    <a href="zh/index.html">Redirecting...</a>' \
            '  </body>' \
            '</html>' \
            > docs/_build/html/index.html

          touch docs/_build/html/.nojekyll

      - name: Setup Pages
        uses: actions/configure-pages@v5

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: docs/_build/html

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
label_issue .github/workflows/label_issue.yml
Triggers
issues
Runs on
ubuntu-latest
Jobs
label_issue
Commands
  • LABEL="" NPU_KEYWORDS=(npu huawei ascend 华为 昇腾 910) ISSUE_TITLE_LOWER=$(echo $ISSUE_TITLE | tr '[:upper:]' '[:lower:]') for KEYWORD in ${NPU_KEYWORDS[@]}; do if [[ $ISSUE_TITLE_LOWER == *$KEYWORD* ]] && [[ $ISSUE_TITLE_LOWER != *input* ]]; then LABEL="npu" break fi done if [ -n "$LABEL" ]; then gh issue edit $ISSUE_URL --add-label $LABEL fi
View raw YAML
name: label_issue

on:
  issues:
    types:
      - opened

jobs:
  label_issue:
    runs-on: ubuntu-latest

    permissions:
      issues: write

    steps:
      - env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ISSUE_URL: ${{ github.event.issue.html_url }}
          ISSUE_TITLE: ${{ github.event.issue.title }}
        run: |
          LABEL=""
          NPU_KEYWORDS=(npu huawei ascend 华为 昇腾 910)
          ISSUE_TITLE_LOWER=$(echo $ISSUE_TITLE | tr '[:upper:]' '[:lower:]')
          for KEYWORD in ${NPU_KEYWORDS[@]}; do
            if [[ $ISSUE_TITLE_LOWER == *$KEYWORD* ]] && [[ $ISSUE_TITLE_LOWER != *input* ]]; then
              LABEL="npu"
              break
            fi
          done
          if [ -n "$LABEL" ]; then
            gh issue edit $ISSUE_URL --add-label $LABEL
          fi
publish .github/workflows/publish.yml
Triggers
workflow_dispatch, release
Runs on
ubuntu-latest
Jobs
publish
Actions
astral-sh/setup-uv, pypa/gh-action-pypi-publish
Commands
  • make build
View raw YAML
name: publish

on:
  workflow_dispatch:
  release:
    types:
      - published

jobs:
  publish:
    name: Upload release to PyPI

    runs-on: ubuntu-latest

    environment:
      name: release
      url: https://pypi.org/p/llamafactory

    permissions:
      id-token: write

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.11"
          github-token: ${{ github.token }}

      - name: Build package
        run: |
          make build

      - name: Publish package
        uses: pypa/gh-action-pypi-publish@release/v1
tests matrix .github/workflows/tests.yml
Triggers
workflow_dispatch, push, pull_request
Runs on
${{ matrix.os }}
Jobs
tests
Matrix
include, include.os, include.python, include.transformers, os, python, transformers→ , 3.11, 3.12, 3.13, 4.55.0, 4.57.1, macos-latest, ubuntu-latest, windows-latest
Actions
astral-sh/setup-uv
Commands
  • uv venv uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu uv pip install -e . uv pip install -r requirements/dev.txt
  • uv pip install "transformers==${{ matrix.transformers }}"
  • make style && make quality
  • make license
  • make build
  • make test
View raw YAML
name: tests

on:
  workflow_dispatch:
  push:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "Makefile"
      - ".github/workflows/*.yml"
  pull_request:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "Makefile"
      - ".github/workflows/*.yml"

jobs:
  tests:
    strategy:
      fail-fast: false
      matrix:
        python:
          - "3.11"
          - "3.12"
          - "3.13"
        os:
          - "ubuntu-latest"
          - "windows-latest"
          - "macos-latest"
        transformers:
          - ""
        include:  # test backward compatibility
          - python: "3.11"
            os: "ubuntu-latest"
            transformers: "4.55.0"
          - python: "3.11"
            os: "ubuntu-latest"
            transformers: "4.57.1"

    runs-on: ${{ matrix.os }}

    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.python }}-${{ matrix.transformers }}
      cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

    env:
      HF_TOKEN: ${{ secrets.HF_TOKEN }}
      OS_NAME: ${{ matrix.os }}
      UV_NO_SYNC: 1

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: ${{ matrix.python }}
          github-token: ${{ github.token }}
          enable-cache: false

      - name: Install dependencies
        run: |
          uv venv
          uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
          uv pip install -e .
          uv pip install -r requirements/dev.txt

      - name: Install transformers
        if: ${{ matrix.transformers }}
        run: |
          uv pip install "transformers==${{ matrix.transformers }}"

      - name: Cache files
        id: hf-hub-cache
        uses: actions/cache@v5
        with:
          path: ${{ runner.temp }}/huggingface
          key: huggingface-${{ matrix.os }}-${{ matrix.python }}-${{ matrix.transformers }}-${{ hashFiles('tests/version.txt') }}

      - name: Check quality
        run: |
          make style && make quality

      - name: Check license
        run: |
          make license

      - name: Check build
        run: |
          make build

      - name: Test with pytest
        run: |
          make test
        env:
          HF_HOME: ${{ runner.temp }}/huggingface
          HF_HUB_OFFLINE: "${{ steps.hf-hub-cache.outputs.cache-hit == 'true' && '1' || '0' }}"
tests_cuda matrix .github/workflows/tests_cuda.yml
Triggers
workflow_dispatch, push, pull_request
Runs on
${{ matrix.os }}
Jobs
tests
Matrix
os, python→ 3.11, linux-x86_64-gpu-2
Actions
astral-sh/setup-uv
Commands
  • nvidia-smi
  • uv venv uv pip install -e . uv pip install -r requirements/dev.txt uv pip install -r requirements/bitsandbytes.txt
  • make style && make quality
  • make license
  • make build
  • make test
View raw YAML
name: tests_cuda

on:
  workflow_dispatch:
  push:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "Makefile"
      - ".github/workflows/*.yml"
  pull_request:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "Makefile"
      - ".github/workflows/*.yml"

jobs:
  tests:
    strategy:
      fail-fast: false
      matrix:
        python:
          - "3.11"
        os:
          - "linux-x86_64-gpu-2"

    runs-on: ${{ matrix.os }}

    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.python }}
      cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

    env:
      HF_HOME: "${{ github.workspace }}/../.runner_cache/huggingface"
      UV_CACHE_DIR: "${{ github.workspace }}/../.runner_cache/uv"
      HF_TOKEN: ${{ secrets.HF_TOKEN }}
      OS_NAME: ${{ matrix.os }}
      UV_NO_SYNC: 1

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: ${{ matrix.python }}
          github-token: ${{ github.token }}
          enable-cache: false

      - name: Check GPU Status
        run: nvidia-smi

      - name: Install dependencies
        run: |
          uv venv
          uv pip install -e .
          uv pip install -r requirements/dev.txt
          uv pip install -r requirements/bitsandbytes.txt

      - name: Check quality
        run: |
          make style && make quality

      - name: Check license
        run: |
          make license

      - name: Check build
        run: |
          make build

      - name: Test with pytest
        run: |
          make test
tests_npu matrix .github/workflows/tests_npu.yml
Triggers
workflow_dispatch, push, pull_request
Runs on
${{ matrix.os }}
Jobs
tests
Matrix
os, python, pytorch_npu→ 2.7.1, 3.11, linux-aarch64-a2-4
Actions
astral-sh/setup-uv
Commands
  • sed -Ei 's@(ports|archive).ubuntu.com@cache-service.nginx-pypi-cache.svc.cluster.local:8081@g' /etc/apt/sources.list pip config set global.index-url http://cache-service.nginx-pypi-cache.svc.cluster.local/pypi/simple pip config set global.trusted-host cache-service.nginx-pypi-cache.svc.cluster.local
  • uv venv uv pip install -r requirements/npu.txt uv pip install -e . uv pip install -r requirements/dev.txt
  • apt-get update || true apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs
  • make style && make quality
  • make license
  • make build
  • make test
View raw YAML
name: tests_npu

on:
  workflow_dispatch:
  push:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "Makefile"
      - ".github/workflows/*.yml"
  pull_request:
    branches:
      - "main"
    paths:
      - "**/*.py"
      - "pyproject.toml"
      - "Makefile"
      - ".github/workflows/*.yml"

jobs:
  tests:
    strategy:
      fail-fast: false
      matrix:
        python:
          - "3.11"
        os:
          - "linux-aarch64-a2-4"
        pytorch_npu:
          - "2.7.1"

    runs-on: ${{ matrix.os }}

    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.python }}
      cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

    container:
      image: ascendai/cann:8.3.rc2-910b-ubuntu22.04-py3.11
      env:
        HF_ENDPOINT: https://hf-mirror.com
        HF_TOKEN: ${{ secrets.HF_TOKEN }}
        OS_NAME: ${{ matrix.os }}
        UV_NO_SYNC: 1

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Set nginx-cache for Ascend CI
        run: |
          sed -Ei 's@(ports|archive).ubuntu.com@cache-service.nginx-pypi-cache.svc.cluster.local:8081@g' /etc/apt/sources.list
          pip config set global.index-url http://cache-service.nginx-pypi-cache.svc.cluster.local/pypi/simple
          pip config set global.trusted-host cache-service.nginx-pypi-cache.svc.cluster.local

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: ${{ matrix.python }}
          github-token: ${{ github.token }}
          enable-cache: false

      - name: Install dependencies
        run: |
          uv venv
          uv pip install -r requirements/npu.txt
          uv pip install -e .
          uv pip install -r requirements/dev.txt

      - name: Install node
        run: |
          apt-get update || true
          apt-get install -y curl
          curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
          apt-get install -y nodejs

      - name: Check quality
        run: |
          make style && make quality

      - name: Check license
        run: |
          make license

      - name: Check build
        run: |
          make build

      - name: Test with pytest
        run: |
          make test