Skip to content

Build All ROCm Wheels #5

Build All ROCm Wheels

Build All ROCm Wheels #5

name: Build All ROCm Wheels
on:
workflow_dispatch:
inputs:
version:
description: 'Version tag of llama-cpp-python to build: v0.2.14'
default: 'v0.2.14'
required: true
type: string
config:
description: 'Override configurations to build: key1:item1-1,item1-2;key2:item2-1,item2-2'
default: 'Default'
required: false
type: string
exclude:
description: 'Exclude build configurations: key1-1:item1-1,key1-2:item1-2;key2-1:item2-1,key2-2:item2-2'
default: 'Default'
required: false
type: string
workflow_call:
inputs:
version:
description: 'Version tag of llama-cpp-python to build: v0.2.14'
default: 'v0.2.14'
required: true
type: string
config:
description: 'Configurations to build: key1:item1-1,item1-2;key2:item2-1,item2-2'
default: 'Default'
required: false
type: string
exclude:
description: 'Exclude build configurations: key1-1:item1-1,key1-2:item1-2;key2-1:item2-1,key2-2:item2-2'
default: 'Default'
required: false
type: string
permissions:
contents: write
jobs:
define_matrix:
name: Define Build Matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
defaults:
run:
shell: pwsh
env:
CONFIGIN: ${{ inputs.config }}
EXCLUDEIN: ${{ inputs.exclude }}
steps:
- name: Define Job Output
id: set-matrix
run: |
$matrix = @{
'os' = 'ubuntu-20.04', 'windows-latest'
'pyver' = "3.10", "3.8", "3.9", "3.11"
'rocm' = '5.4.2', '5.5', '5.5.1', '5.6.1'
'avx' = "AVX", "AVX2", "basic"
'rename' = '0', '1'
'exclude' = @(
@{'os' = 'windows-latest';'rocm' = '5.4.2'},
@{'os' = 'windows-latest';'rocm' = '5.5'},
@{'os' = 'windows-latest';'rocm' = '5.6.1'},
@{'os' = 'ubuntu-20.04';'rocm' = '5.5.1'}
)
}
if ($env:CONFIGIN -ne 'Default') {$env:CONFIGIN.split(';').foreach({$matrix[$_.split(':')[0]] = $_.split(':')[1].split(',')})}
if ($env:EXCLUDEIN -notin ('None','Default')) {
$exclusions = $matrix['exclude']
$exclusions += $env:EXCLUDEIN.split(';').replace(':','=').replace(',',"`n") | ConvertFrom-StringData
$matrix['exclude'] = $exclusions
} elseif ($env:EXCLUDEIN -eq 'None') {$matrix.remove('exclude')}
$matrixOut = ConvertTo-Json $matrix -Compress
Write-Output ('matrix=' + $matrixOut) >> $env:GITHUB_OUTPUT
build_wheels:
name: Build ${{ matrix.os }} ${{ matrix.avx }} ROCm ${{ matrix.rocm }} ${{ matrix.rename == '1' && 'Textgen Wheel' || 'Wheel' }} ${{ matrix.pyver }}
needs: define_matrix
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJSON(needs.define_matrix.outputs.matrix) }}
defaults:
run:
shell: pwsh
env:
PCKGVER: ${{ inputs.version }}
ROCM_VERSION: ${{ matrix.rocm }}
AVXVER: ${{ matrix.avx }}
steps:
- name: Free Disk Space
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@v1.2.0
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
swap-storage: false
- uses: actions/checkout@v4
with:
repository: 'abetlen/llama-cpp-python'
ref: ${{ inputs.version }}
submodules: 'recursive'
- name: Install Linux ROCm SDK
if: runner.os == 'Linux'
shell: bash
run: |
[ ! -d /etc/apt/keyrings ] && sudo mkdir --parents --mode=0755 /etc/apt/keyrings
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg > /dev/null
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/$ROCM_VERSION focal main" | sudo tee --append /etc/apt/sources.list.d/rocm.list
echo -e 'Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600' | sudo tee /etc/apt/preferences.d/rocm-pin-600
sudo apt update
sudo apt install rocm-dev rocblas-dev hipblas-dev -y
- name: Install Windows ROCm SDK
if: runner.os == 'Windows'
run: |
curl -LO https://download.amd.com/developer/eula/rocm-hub/AMD-Software-PRO-Edition-23.Q3-Win10-Win11-For-HIP.exe
Start-Process 'AMD-Software-PRO-Edition-23.Q3-Win10-Win11-For-HIP.exe' -ArgumentList '-install' -NoNewWindow -Wait
echo "C:\Program Files\AMD\ROCm\5.5\bin" >> $env:GITHUB_PATH
echo 'ROCM_PATH=C:\Program Files\AMD\ROCm\5.5' >> $env:GITHUB_ENV
echo 'HIP_PATH=C:\Program Files\AMD\ROCm\5.5' >> $env:GITHUB_ENV
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.pyver }}
- name: Install Dependencies
run: |
python -m pip install build wheel cmake scikit-build ninja
- name: Change Package Name
if: matrix.rename == '1'
run: |
$packageVersion = [version]$env:PCKGVER.TrimStart('v')
$pyproject = Get-Content 'pyproject.toml' -raw
$cmakelists = Get-Content 'CMakeLists.txt' -raw
if ($packageVersion -lt [version]'0.2.0') {
$setup = Get-Content 'setup.py' -raw
$regexstr = '(?s)name="llama_cpp_python",(.+)(package_dir={"llama_cpp": "llama_cpp", "llama_cpp.server": "llama_cpp/server"},.+?packages=\["llama_cpp", "llama_cpp.server"],)'
if ($packageVersion -gt [version]'0.1.77') {$regexstr = '(?s)name="llama_cpp_python",(.+)(package_dir={"llama_cpp": "llama_cpp", "llama_cpp.server": "llama_cpp/server"},.+?package_data={"llama_cpp": \["py.typed"]},.+?packages=\["llama_cpp", "llama_cpp.server"],)'}
$regexmatch = [Regex]::Matches($setup,$regexstr)
if (!($regexmatch[0].Success)) {throw 'setup.py parsing failed'}
$newstr = 'name="llama_cpp_python_cuda",' + $regexmatch[0].Groups[1].Value + $regexmatch[0].Groups[2].Value.Replace('llama_cpp','llama_cpp_cuda')
$newsetup = $regexmatch[0].Result(('$`'+$newstr+'$'''))
New-Item 'setup.py' -itemType File -value $newsetup -force
$regexstr = '(?s)(?<=name = ")llama_cpp_python(".+?packages = \[{include = ")llama_cpp(".+)'
$regexmatch = [Regex]::Matches($pyproject,$regexstr)
if (!($regexmatch[0].Success)) {throw 'pyproject.toml parsing failed'}
$newpyproject = $regexmatch[0].Result(('$`'+'llama_cpp_python_cuda'+'$1llama_cpp_cuda$2'))
} else {
$regexstr = '(?s)(?<=\[project]\s+?name = ")llama_cpp_python(".+?all = \[\s+?")llama_cpp_python(\[.+?wheel.packages = \[")llama_cpp("].+?input = ")llama_cpp(?=/__init__.py")'
$regexmatch = [Regex]::Matches($pyproject,$regexstr)
if (!($regexmatch[0].Success)) {throw 'pyproject.toml parsing failed'}
$newpyproject = $regexmatch[0].Result(('$`' + 'llama_cpp_python_cuda' + '$1llama_cpp_cuda$2' + 'llama_cpp_cuda$3llama_cpp_cuda' + '$'''))
}
Copy-Item 'llama_cpp' 'llama_cpp_cuda' -recurse
New-Item 'pyproject.toml' -itemType File -value $newpyproject -force
New-Item 'CMakeLists.txt' -itemType File -value $cmakelists.Replace('llama_cpp','llama_cpp_cuda') -force
if ($packageVersion -gt [version]'0.2.13')
{
$pyScripts = (Get-ChildItem $(Join-Path '.' 'llama_cpp_cuda' '*.py'))
$pyScripts.fullname.foreach({New-Item $_ -itemType File -value (Get-Content $_ -raw).replace('import llama_cpp.llama','from . import llama') -force})
}
- name: Build Wheel
run: |
if ($IsLinux) {
$env:CC = '/opt/rocm/llvm/bin/clang'
$env:CXX = '/opt/rocm/llvm/bin/clang++'
$env:CFLAGS = '-fPIC'
$env:CXXFLAGS = '-fPIC'
$env:CMAKE_PREFIX_PATH = '/opt/rocm'
$env:GITHUB_PATH = "/opt/rocm/bin:$env:GITHUB_PATH"
$env:ROCM_PATH = "/opt/rocm"
$env:HIP_PATH = "/opt/rocm"
} else {
$env:CC = 'C:\Program Files\AMD\ROCm\5.5\bin\clang.exe'
$env:CXX = 'C:\Program Files\AMD\ROCm\5.5\bin\clang++.exe'
$env:CMAKE_PREFIX_PATH = 'C:\Program Files\AMD\ROCm\5.5'
$cmakelists = Get-Content 'CMakeLists.txt' -raw
$regexstr = '(?s)(?<=\n)\s+?install\(\s+FILES \$\<TARGET_RUNTIME_DLLS.+/llama_cpp(?:_cuda)?\s+\)\s+?(?=endif\(\))'
$regexmatch = [Regex]::Matches($cmakelists,$regexstr)
if ($regexmatch[0].Success) {New-Item 'CMakeLists.txt' -itemType File -value $regexmatch[0].Result('$`$''') -force}
}
$env:VERBOSE = '1'
$packageVersion = [version]$env:PCKGVER.TrimStart('v')
$gputargets = 'gfx803;gfx900;gfx906:xnack-;gfx908:xnack-;gfx90a:xnack+;gfx90a:xnack-;gfx1010;gfx1012;gfx1030;gfx1100;gfx1101;gfx1102'
if ([version]$env:ROCM_VERSION -lt [version]'5.5') {$gputargets = 'gfx803;gfx900;gfx906:xnack-;gfx908:xnack-;gfx90a:xnack+;gfx90a:xnack-;gfx1010;gfx1012;gfx1030'}
if ($env:AVXVER -eq 'AVX') {$env:CMAKE_ARGS = "-GNinja -DLLAMA_HIPBLAS=ON -DLLAMA_AVX2=off -DLLAMA_FMA=off -DLLAMA_F16C=off -DGPU_TARGETS=$gputargets"}
if ($env:AVXVER -eq 'AVX512') {$env:CMAKE_ARGS = "-GNinja -DLLAMA_HIPBLAS=ON -DLLAMA_AVX512=on -DGPU_TARGETS=$gputargets"}
if ($env:AVXVER -eq 'basic') {$env:CMAKE_ARGS = "-GNinja -DLLAMA_HIPBLAS=ON -DLLAMA_AVX=off -DLLAMA_AVX2=off -DLLAMA_FMA=off -DLLAMA_F16C=off -DGPU_TARGETS=$gputargets"}
if ($env:AVXVER -eq 'AVX2')
{
$env:CMAKE_ARGS = "-GNinja -DLLAMA_HIPBLAS=ON -DGPU_TARGETS=$gputargets"
$buildtag = "+rocm$env:ROCM_VERSION"
} else {$buildtag = "+rocm$env:ROCM_VERSION$env:AVXVER"}
if ($packageVersion -gt [version]'0.2.13') {$env:CMAKE_ARGS = "-DLLAMA_NATIVE=off $env:CMAKE_ARGS"}
if ($packageVersion -lt [version]'0.2.0') {
python -m build --wheel -C--build-option=egg_info "-C--build-option=--tag-build=$buildtag"
} else {
$initpath = Join-Path '.' '${{ matrix.rename == '1' && 'llama_cpp_cuda' || 'llama_cpp' }}' '__init__.py' -resolve
$initcontent = Get-Content $initpath -raw
$regexstr = '(?s)(?<=__version__ \= ")\d+(?:\.\d+)*(?=")'
$regexmatch = [Regex]::Matches($initcontent,$regexstr)
if (!($regexmatch[0].Success)) {throw '__init__.py parsing failed'}
$newinit = $regexmatch[0].Result(('$`' + '$&' + $buildtag + '$'''))
New-Item $initpath -itemType File -value $newinit -force
python -m build --wheel
}
- name: Upload files to a GitHub release
id: upload-release
uses: svenstaro/upload-release-action@2.7.0
continue-on-error: true
with:
file: ./dist/*.whl
tag: rocm
file_glob: true
make_latest: false
overwrite: true
- uses: actions/upload-artifact@v3
if: steps.upload-release.outcome == 'failure'
with:
name: 'rocm-wheels'
path: ./dist/*.whl