Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions .github/workflows/build-wheels-cpu-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Build Wheels(CPU) for Linux

on:
workflow_dispatch: # Manual trigger

permissions:
contents: write

jobs:
build_wheels:
name: Build Wheel ${{ matrix.os }} ${{ matrix.pyver }} CPU ${{ matrix.releasetag == 'wheels' && 'AVX2' || matrix.releasetag }}
runs-on: ubuntu-22.04
strategy:
matrix: # Define the build matrix directly here
os: ["ubuntu-22.04"]
pyver: ["3.10", "3.11", "3.12", "3.13", "3.14"] # Python versions
releasetag: ["Basic"] # Controls CMAKE_ARGS for CPU features (even in CUDA build)

defaults:
run:
shell: bash

env:
AVXVER: ${{ matrix.releasetag }}

steps:
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y build-essential ccache cmake curl git libgomp1 libjpeg-dev libssl-dev libopenblas-dev

- uses: actions/checkout@v6 # Checkout code
with:
submodules: "recursive"

# from astral-sh/setup-uv
- name: Install the latest version of uv and set the python version
uses: astral-sh/setup-uv@v6
with:
python-version: ${{ matrix.pyver }}
activate-environment: true
enable-cache: true

- name: Build Wheel With Cmake # Main build step: configures and builds the wheel
env:
VERBOSE: 1 # Enable verbose build output
run: |
echo "VERBOSE=1" >> $GITHUB_ENV # Enable verbose build output for troubleshooting

# Add project-specific and feature flags
CMAKE_ARGS="-DGGML_BLAS=on -DGGML_BLAS_VENDOR=OpenBLAS"
CMAKE_ARGS="${CMAKE_ARGS} -DLLAMA_CURL=off -DLLAMA_OPENSSL=on"

if [ "${AVXVER}" = "AVX" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DGGML_AVX=on -DGGML_AVX2=off -DGGML_AVX512=off -DGGML_FMA=off -DGGML_F16C=off"
fi
if [ "${AVXVER}" = "AVX2" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DGGML_AVX=on -DGGML_AVX2=on -DGGML_AVX512=off"
fi
if [ "${AVXVER}" = "AVXVNNI" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DGGML_AVX=on -DGGML_AVX2=on -DGGML_AVX_VNNI=on"
fi
# if [ "${AVXVER}" = "AVX512" ]; then
# CMAKE_ARGS="${CMAKE_ARGS} -DGGML_AVX512=on"
# fi
# Basic options for compiling without AVX instructions
if [ "${AVXVER}" = "Basic" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DGGML_NATIVE=off -DGGML_AVX=off -DGGML_AVX2=off -DGGML_AVX_VNNI=off -DGGML_AVX512=off -DGGML_AVX512_VBMI=off -DGGML_AVX512_VNNI=off -DGGML_AVX512_BF16=off -DGGML_FMA=off -DGGML_F16C=off"
fi

# Export CMAKE_ARGS environment variable so the python -m build command can use it
echo ${CMAKE_ARGS}
echo "CMAKE_ARGS=${CMAKE_ARGS}" >> $GITHUB_ENV

# Run the Python build command to generate the wheel
uv pip install build setuptools wheel packaging
CMAKE_ARGS=${CMAKE_ARGS} uv build --wheel

# --- Post-build steps to get info for rename wheel file and release tag ---

avx_ver=$(echo "${AVXVER}" | tr '[:upper:]' '[:lower:]')

wheel_path=$(ls dist/*.whl | head -n 1)
filename=$(basename "$wheel_path")

# Split wheel filename
IFS='-' read -r dist_name version py_tag abi_tag plat_tag <<< "$filename"

new_version="${version}+cpu.${avx_ver}"
new_filename="${dist_name}-${new_version}-${py_tag}-${abi_tag}-${plat_tag}"

# Rename wheel file
mv "$wheel_path" "dist/$new_filename"
echo "Renamed wheel to: $new_filename"

echo "TAG_VERSION=$version" >> $GITHUB_ENV # Store version in env for release step

- name: Get Current Date # Step to get current date for the release tag
id: get-date
run: |
# Get date in YYYYMMDD format using bash date command
currentDate=$(date +%Y%m%d)
# Store the date in environment variable for the release step
echo "BUILD_DATE=$currentDate" >> $GITHUB_ENV

- name: Create Git Tag
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git tag "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-linux-${{ env.BUILD_DATE }}"
git push origin "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-linux-${{ env.BUILD_DATE }}"

Comment on lines +106 to +112
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Create Git Tag step will conflict with the job matrix: every Python-version run will attempt to create/push the same tag (v<TAG_VERSION>-cpu-<AVXVER>-linux-<BUILD_DATE>). This will cause the later matrix jobs to fail, and re-running the workflow on the same day/version will also fail if the tag already exists. Consider removing the explicit git tag/git push and relying on softprops/action-gh-release to create/update the tag, or gate tag/release creation to a single matrix entry and publish all wheels from a dedicated release job that downloads artifacts from the build matrix.

Suggested change
- name: Create Git Tag
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git tag "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-linux-${{ env.BUILD_DATE }}"
git push origin "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-linux-${{ env.BUILD_DATE }}"

Copilot uses AI. Check for mistakes.
- uses: softprops/action-gh-release@v2.2.2 # Action to create a GitHub Release
with:
files: dist/* # Upload the generated wheel files from the dist directory
# Define the release tag name using the collected environment variables
# Format: v<package_version>-cpu-<avx_tag>-linux-<build_date>
tag_name: v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-linux-${{ env.BUILD_DATE }} # Release tag format for Linux
# Note: This action will create a new release tag if it doesn't exist,
# or upload assets to an existing tag. Be mindful of potential tag name conflicts.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use the secret provided by GitHub Actions for authentication
121 changes: 121 additions & 0 deletions .github/workflows/build-wheels-cpu-win.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Build Wheels (CPU) for Windows

on:
workflow_dispatch:

permissions:
contents: write

jobs:
build_wheels:
name: Build Wheel ${{ matrix.os }} ${{ matrix.pyver }} CPU ${{ matrix.releasetag }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ['windows-2022']
pyver: ["3.10", "3.11", "3.12", "3.13", "3.14"]
releasetag: ["Basic"]
defaults:
run:
shell: pwsh
env:
AVXVER: ${{ matrix.releasetag }}
MAX_JOBS: 8

steps:
- name: Add MSBuild to PATH
if: runner.os == 'Windows'
uses: microsoft/setup-msbuild@v3
with:
msbuild-architecture: x64

- uses: actions/checkout@v6
with:
submodules: "recursive"

# from astral-sh/setup-uv
- name: Install the latest version of uv and set the python version
uses: astral-sh/setup-uv@v6
with:
python-version: ${{ matrix.pyver }}
activate-environment: true
enable-cache: true

- name: Install Dependencies
run: |
git config --system core.longpaths true
uv pip install --upgrade build setuptools wheel packaging

- name: Build Wheel
run: |
$env:VERBOSE = '1'
$env:CMAKE_ARGS = '-DCMAKE_BUILD_PARALLEL_LEVEL=' + $env:MAX_JOBS
$env:CMAKE_ARGS = "-DENABLE_CCACHE=on -DLLAMA_CURL=off $env:CMAKE_ARGS"

if ($env:AVXVER -eq 'AVX') {
$env:CMAKE_ARGS = $env:CMAKE_ARGS + ' -DGGML_AVX=on -DGGML_AVX2=off -DGGML_AVX512=off -DGGML_FMA=off -DGGML_F16C=off'
}
if ($env:AVXVER -eq 'AVX2') {
$env:CMAKE_ARGS = $env:CMAKE_ARGS + ' -DGGML_AVX=on -DGGML_AVX2=on -DGGML_AVX512=off'
}
if ($env:AVXVER -eq 'AVXVNNI') {
$env:CMAKE_ARGS = $env:CMAKE_ARGS + ' -DGGML_AVX=on -DGGML_AVX2=on -DGGML_AVX_VNNI=on'
}
# if ($env:AVXVER -eq 'AVX512') {
# $env:CMAKE_ARGS = $env:CMAKE_ARGS + ' -DGGML_AVX512=on'
# }
# Basic options for compiling without AVX instructions
if ($env:AVXVER -eq 'Basic') {
$env:CMAKE_ARGS = $env:CMAKE_ARGS + ' -DGGML_NATIVE=off -DGGML_AVX=off -DGGML_AVX2=off -DGGML_AVX_VNNI=off -DGGML_AVX512=off -DGGML_AVX512_VBMI=off -DGGML_AVX512_VNNI=off -DGGML_AVX512_BF16=off -DGGML_FMA=off -DGGML_F16C=off'
}
python -m build --wheel

# Check if wheel was built
if (!(Test-Path '.\dist\*.whl')) {
Write-Error "No wheel built in dist/ directory"
exit 1
}

$wheelFile = Get-Item '.\dist\*.whl' | Select-Object -First 1

# Split file name: name-ver-py-abi-plat.whl
$parts = $wheelFile.Name.Split('-')
$distName = $parts[0]
$version = $parts[1]
$pyTag = $parts[2]
$abiTag = $parts[3]
$platTag = $parts[4]

$newVersion = "$version+cpu.$($env:AVXVER.ToLower())"

$newName = "$distName-$newVersion-$pyTag-$abiTag-$platTag"

# Rename wheel file
Rename-Item -Path $wheelFile.FullName -NewName $newName
Write-Output "Renamed wheel to: $newName"

# write the build tag to the output
Write-Output "TAG_VERSION=$version" >> $env:GITHUB_ENV

- name: Get Current Date
id: get-date
run: |
$currentDate = Get-Date -UFormat "%Y%m%d"
Write-Output "BUILD_DATE=$currentDate" >> $env:GITHUB_ENV

- name: Create Git Tag
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git tag "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-win-${{ env.BUILD_DATE }}"
git push origin "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-win-${{ env.BUILD_DATE }}"

- name: Create Release
if: always() && env.TAG_VERSION != ''
uses: softprops/action-gh-release@v2
with:
files: dist/*
Comment on lines +100 to +117
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Create Git Tag step will deterministically conflict in the current matrix setup: each Python-version job tries to create and push the exact same tag (v<TAG_VERSION>-cpu-<AVXVER>-win-<BUILD_DATE>). The first job to push will win; subsequent jobs will fail (and a workflow re-run on the same day/version will also fail because the tag already exists). Prefer removing the manual git tag/git push and letting softprops/action-gh-release manage the tag, or gate tag/release creation to a single matrix entry and use artifacts + a separate release job to publish all wheels under one tag/release.

Suggested change
- name: Get Current Date
id: get-date
run: |
$currentDate = Get-Date -UFormat "%Y%m%d"
Write-Output "BUILD_DATE=$currentDate" >> $env:GITHUB_ENV
- name: Create Git Tag
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git tag "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-win-${{ env.BUILD_DATE }}"
git push origin "v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-win-${{ env.BUILD_DATE }}"
- name: Create Release
if: always() && env.TAG_VERSION != ''
uses: softprops/action-gh-release@v2
with:
files: dist/*
- name: Upload Built Wheels
if: always() && env.TAG_VERSION != ''
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.pyver }}-${{ matrix.releasetag }}
path: dist/*
if-no-files-found: error
release:
name: Create Windows CPU Release
needs: build_wheels
runs-on: windows-2022
defaults:
run:
shell: pwsh
env:
AVXVER: Basic
steps:
- uses: actions/checkout@v6
with:
submodules: "recursive"
- name: Download Built Wheels
uses: actions/download-artifact@v4
with:
path: dist
pattern: wheels-*
merge-multiple: true
- name: Get Package Version
run: |
$version = (Select-String -Path "setup.py" -Pattern 'version\s*=\s*"([^"]+)"').Matches[0].Groups[1].Value
Write-Output "TAG_VERSION=$version" >> $env:GITHUB_ENV
- name: Get Current Date
run: |
$currentDate = Get-Date -UFormat "%Y%m%d"
Write-Output "BUILD_DATE=$currentDate" >> $env:GITHUB_ENV
- name: Create Release
if: always() && env.TAG_VERSION != ''
uses: softprops/action-gh-release@v2
with:
files: dist/**/*

Copilot uses AI. Check for mistakes.
# Set tag_name to <tag>-cpu-<avxver>-win-<date>
tag_name: v${{ env.TAG_VERSION }}-cpu-${{ env.AVXVER }}-win-${{ env.BUILD_DATE }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading