feat: setup automated nightly builds for CachyLLama and llama-ai

This commit is contained in:
John Smith
2026-08-20 18:58:06 -04:00
commit 58fb465cfe
16 changed files with 1975 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
name: Bug Report
description: File a bug report for CachyLLama-BUILDER automated builds or packages
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: dropdown
id: artifact-type
attributes:
label: Build Artifact Type
description: Which build artifact are you having issues with?
options:
- Linux ROCm (gfx1151 - Strix Halo)
- Linux ROCm (gfx1150 - Strix Point)
- Linux ROCm (gfx110X - Phoenix / 780M / 7900XTX)
- Linux ROCm (gfx103X - Steam Deck / 680M)
- Linux Vulkan
- Windows ROCm
- Windows CPU / CUDA
- macOS Metal
- llama-ai Turnkey Bundle
validations:
required: true
- type: input
id: release-tag
attributes:
label: Release Tag / Build Number
description: E.g., b1001, latest nightly, or specific commit hash.
placeholder: b1001
validations:
required: true
- type: textarea
id: hardware
attributes:
label: Hardware & OS Details
description: CPU, GPU, OS distribution, kernel version, ROCm/driver version.
placeholder: AMD Ryzen AI Max+ 395, Radeon 8060S, Bazzite 41 (Kernel 6.13)
validations:
required: true
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what happened.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant Log Output
description: Please copy and paste any relevant terminal or GitHub Actions logs.
render: shell
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: CachyLLama Core Discussions
url: https://github.com/fewtarius/CachyLLama/discussions
about: Ask questions or discuss CachyLLama algorithms, KV cache, and optimizations.
- name: llama-ai Runtime Discussions
url: https://github.com/fewtarius/llama-ai/discussions
about: Discuss APU configurations, the solver, and autonomous agent orchestration.
@@ -0,0 +1,28 @@
name: Feature Request
description: Suggest an idea or new hardware target for CachyLLama-BUILDER
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thank you for suggesting a new feature or improvement!
- type: textarea
id: feature-description
attributes:
label: Is your feature request related to a problem?
description: A clear and concise description of what you're trying to achieve.
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Describe the solution you'd like
description: A clear description of the new GPU architecture, backend, packaging format, or CI enhancement.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: Any alternative solutions or features considered.
+68
View File
@@ -0,0 +1,68 @@
name: 'Get Next Tag Name'
description: 'Determine next sequential release tag (bXXXX) for CachyLLama builds'
inputs:
github_token:
description: 'GitHub token for querying releases API'
required: false
default: ${{ github.token }}
prefix:
description: 'Tag prefix'
required: false
default: 'b'
outputs:
tag:
description: 'Generated release tag name (e.g. b1001)'
value: ${{ steps.generate-tag.outputs.tag }}
tag_exists:
description: 'Whether the generated tag already exists in remote'
value: ${{ steps.check-tag.outputs.tag_exists }}
runs:
using: "composite"
steps:
- name: Generate sequential release tag
id: generate-tag
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github_token }}
PREFIX: ${{ inputs.prefix }}
run: |
echo "Determining next release tag with prefix '$PREFIX'..."
# Get all existing release tags that match the pattern <prefix>####
existing_tags=$(gh release list --limit 1000 --json tagName --jq '.[].tagName' 2>/dev/null | grep -E "^${PREFIX}[0-9]{4,}$" | sort -V || echo "")
if [ -z "$existing_tags" ]; then
# Fall back to git tags if gh release list is empty
existing_tags=$(git tag -l "${PREFIX}*" | grep -E "^${PREFIX}[0-9]{4,}$" | sort -V || echo "")
fi
if [ -z "$existing_tags" ]; then
next_number=1000
echo "No existing sequential release tags found, starting with ${PREFIX}1000"
else
highest_tag=$(echo "$existing_tags" | tail -n 1)
highest_number=$(echo "$highest_tag" | sed "s/^${PREFIX}//")
next_number=$((highest_number + 1))
echo "Highest existing tag: $highest_tag (number: $highest_number)"
echo "Next number will be: $next_number"
fi
TAG=$(printf "${PREFIX}%04d" "$next_number")
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "Generated release tag: ${TAG}"
- name: Check if tag exists
id: check-tag
shell: bash
run: |
TAG="${{ steps.generate-tag.outputs.tag }}"
if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then
echo "Tag $TAG already exists on remote"
echo "tag_exists=true" >> $GITHUB_OUTPUT
else
echo "Tag $TAG does not exist on remote"
echo "tag_exists=false" >> $GITHUB_OUTPUT
fi
@@ -0,0 +1,143 @@
name: 'Test CachyLLama Build'
description: 'Download and test CachyLLama build artifacts on host GPU'
inputs:
os_type:
description: 'Operating system type (Windows or Linux)'
required: true
gfx_target:
description: 'GPU target (e.g., gfx1151, gfx1150, gfx110X, etc.)'
required: true
artifact_name:
description: 'Full artifact name to download'
required: true
runs:
using: "composite"
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact_name }}
path: llama-binaries
- name: Download test model (Windows)
if: inputs.os_type == 'Windows'
shell: powershell
run: |
$modelUrl = "https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-Q4_0.gguf?download=true"
$modelPath = "Qwen3-0.6B-Q4_0.gguf"
Write-Host "Downloading test model from: $modelUrl"
curl.exe -L -o $modelPath $modelUrl
if (Test-Path $modelPath) {
$fileSize = (Get-Item $modelPath).Length
Write-Host "Model downloaded successfully. Size: $fileSize bytes"
} else {
Write-Error "Failed to download model"
exit 1
}
- name: Download test model (Linux)
if: inputs.os_type == 'Linux'
shell: bash
run: |
model_url="https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-Q4_0.gguf?download=true"
model_path="Qwen3-0.6B-Q4_0.gguf"
echo "Downloading test model from: $model_url"
curl -L -o "$model_path" "$model_url"
if [ -f "$model_path" ]; then
file_size=$(stat -c%s "$model_path")
echo "Model downloaded successfully. Size: $file_size bytes"
else
echo "Failed to download model"
exit 1
fi
- name: Set up library path (Linux)
if: inputs.os_type == 'Linux'
shell: bash
run: |
echo "LD_LIBRARY_PATH=$(pwd)/llama-binaries:${LD_LIBRARY_PATH:-}" >> $GITHUB_ENV
- name: Run llama-cli test (Windows)
if: inputs.os_type == 'Windows'
shell: powershell
run: |
$llamaCliPath = "llama-binaries\llama-cli.exe"
$modelPath = "Qwen3-0.6B-Q4_0.gguf"
if (-not (Test-Path $llamaCliPath)) {
Write-Error "llama-cli.exe not found at: $llamaCliPath"
Get-ChildItem -Recurse "llama-binaries"
exit 1
}
Write-Host "Running CachyLLama CLI test for ${{ inputs.gfx_target }}..."
Write-Host "Command: $llamaCliPath -m `"$modelPath`" -ngl 99 -p `"Hello from CachyLLama!`" -st -v"
try {
$process = Start-Process -FilePath $llamaCliPath -ArgumentList @("-m", "`"$modelPath`"", "-ngl", "99", "-p", "`"Hello from CachyLLama!`"", "-st", "-v") -NoNewWindow -Wait -PassThru -RedirectStandardOutput "stdout.txt" -RedirectStandardError "stderr.txt"
$process.WaitForExit()
$stdout = Get-Content "stdout.txt" -Raw -ErrorAction SilentlyContinue
$stderr = Get-Content "stderr.txt" -Raw -ErrorAction SilentlyContinue
Write-Host "=== CACHYLLAMA-CLI STDOUT ==="
if ($stdout) { Write-Host $stdout } else { Write-Host "(empty)" }
Write-Host "=== CACHYLLAMA-CLI STDERR ==="
if ($stderr) { Write-Host $stderr } else { Write-Host "(empty)" }
Write-Host "Process exit code: $($process.ExitCode)"
Remove-Item "stdout.txt" -ErrorAction SilentlyContinue
Remove-Item "stderr.txt" -ErrorAction SilentlyContinue
}
catch {
Write-Error "Failed to start llama-cli process: $_"
exit 1
}
if ($process.ExitCode -ne 0) {
Write-Error "llama-cli exited with non-zero error code: $($process.ExitCode)"
exit 1
}
Write-Host "✅ Test PASSED on Windows (${{ inputs.gfx_target }})"
- name: Run llama-cli test (Linux)
if: inputs.os_type == 'Linux'
shell: bash
run: |
llama_cli_path="./llama-binaries/llama-cli"
model_path="Qwen3-0.6B-Q4_0.gguf"
output_file="llama_output.txt"
chmod +x "$llama_cli_path"
if [ ! -f "$llama_cli_path" ]; then
echo "llama-cli not found at: $llama_cli_path"
find llama-binaries -type f
exit 1
fi
echo "Running CachyLLama CLI test for ${{ inputs.gfx_target }}..."
set +e
"$llama_cli_path" -m "$model_path" -ngl 99 -p "Hello from CachyLLama!" -st -v > "$output_file" 2>&1
exit_code=$?
set -e
echo "=== CACHYLLAMA-CLI OUTPUT ==="
if [ -f "$output_file" ] && [ -s "$output_file" ]; then
cat "$output_file"
else
echo "(empty)"
fi
echo "Process exit code: $exit_code"
if [ $exit_code -ne 0 ]; then
echo "❌ llama-cli exited with error code: $exit_code"
exit 1
fi
echo "✅ Test PASSED on Linux (${{ inputs.gfx_target }})"
+289
View File
@@ -0,0 +1,289 @@
name: Build CachyLLama Multi-Backend Release
on:
schedule:
- cron: '0 2 * * *' # Nightly at 2:00 AM UTC
workflow_dispatch:
inputs:
cachyllama_version:
description: 'CachyLLama branch or tag to build'
required: false
default: 'master'
create_release:
description: 'Create a GitHub release'
required: false
default: true
type: boolean
pull_request:
paths:
- '.github/workflows/build-cachyllama-all.yml'
- 'scripts/**'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}
cancel-in-progress: true
env:
CACHYLLAMA_VERSION: ${{ github.event.inputs.cachyllama_version || 'master' }}
CACHYLLAMA_REPO: 'https://github.com/fewtarius/CachyLLama.git'
CMAKE_ARGS: "-DLLAMA_BUILD_EXAMPLES=OFF -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_TOOLS=ON -DLLAMA_BUILD_SERVER=ON -DGGML_RPC=ON"
jobs:
ubuntu-vulkan:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build libvulkan-dev vulkan-tools glslang-tools build-essential
- name: Clone CachyLLama
run: |
git clone --depth 1 --branch "${{ env.CACHYLLAMA_VERSION }}" "${{ env.CACHYLLAMA_REPO }}" CachyLLama
- name: Build with Vulkan backend
run: |
cd CachyLLama
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_VULKAN=ON \
-DGGML_CPU=ON \
-DGGML_NATIVE=OFF \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j $(nproc)
- name: Pack artifacts
run: |
cp CachyLLama/LICENSE CachyLLama/build/bin/
tar -czvf cachy-llama-bin-ubuntu-vulkan-x64.tar.gz -C CachyLLama/build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-bin-ubuntu-vulkan-x64.tar.gz
path: cachy-llama-bin-ubuntu-vulkan-x64.tar.gz
ubuntu-cpu:
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- build: 'x64'
os: ubuntu-22.04
- build: 'arm64'
os: ubuntu-24.04-arm
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build build-essential
- name: Clone CachyLLama
run: |
git clone --depth 1 --branch "${{ env.CACHYLLAMA_VERSION }}" "${{ env.CACHYLLAMA_REPO }}" CachyLLama
- name: Build CPU backend
run: |
cd CachyLLama
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_CPU_ALL_VARIANTS=ON \
-DGGML_NATIVE=OFF \
-DGGML_OPENMP=ON \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j $(nproc)
- name: Pack artifacts
run: |
cp CachyLLama/LICENSE CachyLLama/build/bin/
tar -czvf cachy-llama-bin-ubuntu-cpu-${{ matrix.build }}.tar.gz -C CachyLLama/build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-bin-ubuntu-cpu-${{ matrix.build }}.tar.gz
path: cachy-llama-bin-ubuntu-cpu-${{ matrix.build }}.tar.gz
ubuntu-cuda:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
sm: ${{ github.event_name == 'pull_request' && fromJSON('["sm_89"]') || fromJSON('["sm_75", "sm_80", "sm_86", "sm_89", "sm_90", "sm_100", "sm_120", "sm_121"]') }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Free disk space
run: |
sudo apt-get remove -y '^aspnetcore-.*' '^dotnet-.*' '^llvm-.*' 'php.*' 'ruby.*' \
google-cloud-cli azure-cli google-chrome-stable firefox powershell 2>/dev/null || true
sudo apt-get autoremove -y
df -h
- name: Install CUDA Toolkit
run: |
wget -q https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update
sudo apt-get install -y \
cuda-nvcc-12-8 \
cuda-cudart-dev-12-8 \
cuda-cccl-12-8 \
libcublas-dev-12-8 \
libcurand-dev-12-8 \
libnvjitlink-dev-12-8 \
cmake ninja-build
- name: Clone CachyLLama
run: |
git clone --depth 1 --branch "${{ env.CACHYLLAMA_VERSION }}" "${{ env.CACHYLLAMA_REPO }}" CachyLLama
- name: Build CUDA backend
run: |
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:${LD_LIBRARY_PATH:-}"
cd CachyLLama
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_CUDA=ON \
-DCUDA_ARCHITECTURES="${{ matrix.sm }}" \
-DCMAKE_CUDA_ARCHITECTURES="${{ matrix.sm }}" \
-DGGML_NATIVE=OFF \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j $(nproc)
- name: Pack artifacts
run: |
cp CachyLLama/LICENSE CachyLLama/build/bin/
tar -czvf cachy-llama-bin-ubuntu-cuda-${{ matrix.sm }}-x64.tar.gz -C CachyLLama/build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-bin-ubuntu-cuda-${{ matrix.sm }}-x64.tar.gz
path: cachy-llama-bin-ubuntu-cuda-${{ matrix.sm }}-x64.tar.gz
windows-cpu:
runs-on: windows-2022
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clone CachyLLama
shell: powershell
run: |
git clone --depth 1 --branch "${{ env.CACHYLLAMA_VERSION }}" "${{ env.CACHYLLAMA_REPO }}" CachyLLama
- name: Build Windows CPU
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cd CachyLLama
cmake -B build -A x64 -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=OFF ${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j %NUMBER_OF_PROCESSORS%
- name: Pack artifacts
shell: powershell
run: |
Copy-Item CachyLLama\LICENSE CachyLLama\build\bin\Release\
Compress-Archive -Path CachyLLama\build\bin\Release\* -DestinationPath cachy-llama-bin-windows-cpu-x64.zip
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-bin-windows-cpu-x64.zip
path: cachy-llama-bin-windows-cpu-x64.zip
macos-metal:
runs-on: macos-14
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clone CachyLLama
run: |
git clone --depth 1 --branch "${{ env.CACHYLLAMA_VERSION }}" "${{ env.CACHYLLAMA_REPO }}" CachyLLama
- name: Build macOS Metal
run: |
cd CachyLLama
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_METAL=ON \
-DGGML_METAL_EMBED_LIBRARY=ON \
-DCMAKE_OSX_DEPLOYMENT_TARGET=13.3 \
-DCMAKE_INSTALL_RPATH='@loader_path' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
${{ env.CMAKE_ARGS }}
cmake --build build --config Release -j $(sysctl -n hw.logicalcpu)
- name: Pack artifacts
run: |
cp CachyLLama/LICENSE CachyLLama/build/bin/
tar -czvf cachy-llama-bin-macos-metal-arm64.tar.gz -C CachyLLama/build/bin .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-bin-macos-metal-arm64.tar.gz
path: cachy-llama-bin-macos-metal-arm64.tar.gz
release:
needs: [ubuntu-vulkan, ubuntu-cpu, ubuntu-cuda, windows-cpu, macos-metal]
runs-on: ubuntu-22.04
permissions:
contents: write
if: |
always() &&
github.event_name != 'pull_request' &&
(github.event_name == 'schedule' || github.event.inputs.create_release == 'true' || github.event.inputs.create_release == null)
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./multi-artifacts
- name: Determine tag name
id: tag
uses: ./.github/actions/get-tag-name
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
prefix: 'b'
- name: Prepare release files
run: |
mkdir -p ./release-files
find ./multi-artifacts -type f \( -name "*.tar.gz" -o -name "*.zip" \) -exec cp {} ./release-files/ \;
ls -la ./release-files/
- name: Publish GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.tag.outputs.tag }}"
gh release create "$TAG" \
--title "CachyLLama $TAG (Multi-Backend)" \
--notes "### CachyLLama Multi-Backend Release $TAG
- **Vulkan RADV**: Linux AMD APU / dGPU acceleration
- **CPU**: Linux & Windows x64 / ARM64
- **CUDA**: NVIDIA GPU support (sm_75 to sm_121)
- **Metal**: Apple Silicon macOS acceleration" \
./release-files/*
+554
View File
@@ -0,0 +1,554 @@
name: Build CachyLLama + ROCm Nightly
on:
workflow_dispatch:
inputs:
operating_systems:
description: 'Operating systems to build for (comma-separated: windows,ubuntu)'
required: false
default: 'windows,ubuntu'
gfx_target:
description: 'AMD GPU targets (comma-separated: gfx1151,gfx1150,gfx120X,gfx110X,gfx103X,gfx90a,gfx908)'
required: false
default: 'gfx1151,gfx1150,gfx120X,gfx110X,gfx103X,gfx90a,gfx908'
rocm_version:
description: 'ROCm version to use or "latest" to auto-detect from AMD TheRock'
required: false
default: 'latest'
cachyllama_version:
description: 'CachyLLama version (branch, tag, or commit hash)'
required: false
default: 'master'
create_release:
description: 'Create a GitHub release after successful build'
required: false
default: true
type: boolean
# Trigger on pull requests modifying workflow or scripts
pull_request:
paths:
- '.github/workflows/build-cachyllama-rocm.yml'
- '.github/actions/**'
- 'scripts/**'
# Trigger nightly (1:00 PM UTC = 5:00 AM PST, ~2 hours after ROCm nightly tarballs are published)
schedule:
- cron: '0 13 * * *'
env:
OPERATING_SYSTEMS: ${{ github.event.inputs.operating_systems || 'windows,ubuntu' }}
GFX_TARGETS: ${{ github.event.inputs.gfx_target || 'gfx1151,gfx1150,gfx120X,gfx110X,gfx103X,gfx90a,gfx908' }}
ROCM_VERSION: ${{ github.event.inputs.rocm_version || 'latest' }}
CACHYLLAMA_VERSION: ${{ github.event.inputs.cachyllama_version || 'master' }}
CACHYLLAMA_REPO: 'https://github.com/fewtarius/CachyLLama.git'
jobs:
prepare-matrix:
runs-on: ubuntu-22.04
outputs:
windows_matrix: ${{ steps.set-matrix.outputs.windows_matrix }}
ubuntu_matrix: ${{ steps.set-matrix.outputs.ubuntu_matrix }}
should_build_windows: ${{ steps.set-matrix.outputs.should_build_windows }}
should_build_ubuntu: ${{ steps.set-matrix.outputs.should_build_ubuntu }}
steps:
- name: Set matrix
id: set-matrix
run: |
targets="${{ env.GFX_TARGETS }}"
operating_systems="${{ env.OPERATING_SYSTEMS }}"
echo "Input targets: $targets"
echo "Input operating systems: $operating_systems"
# Convert comma-separated targets into JSON array
matrix_targets=$(echo "$targets" \
| tr ',' '\n' \
| sed 's/^ *//;s/ *$//' \
| sed 's/^"//;s/"$//' \
| jq -R . \
| jq -s '{gfx_target: .}' \
| jq -c)
should_build_windows="false"
should_build_ubuntu="false"
if [[ "$operating_systems" == *"windows"* ]]; then
should_build_windows="true"
echo "windows_matrix=$matrix_targets" >> $GITHUB_OUTPUT
fi
if [[ "$operating_systems" == *"ubuntu"* ]]; then
should_build_ubuntu="true"
echo "ubuntu_matrix=$matrix_targets" >> $GITHUB_OUTPUT
fi
echo "should_build_windows=$should_build_windows" >> $GITHUB_OUTPUT
echo "should_build_ubuntu=$should_build_ubuntu" >> $GITHUB_OUTPUT
echo "Windows build: $should_build_windows"
echo "Ubuntu build: $should_build_ubuntu"
echo "Generated matrix: $matrix_targets"
build-windows:
# Pinned to windows-2022 (VS 2022 / MSVC 14.4x) to avoid MSVC 14.51 <cmath> constexpr collision
runs-on: windows-2022
needs: prepare-matrix
if: needs.prepare-matrix.outputs.should_build_windows == 'true'
strategy:
matrix: ${{ fromJson(needs.prepare-matrix.outputs.windows_matrix) }}
fail-fast: false
outputs:
rocm_version: ${{ steps.set-outputs.outputs.rocm_version }}
cachyllama_commit_hash: ${{ steps.set-outputs.outputs.cachyllama_commit_hash }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clean up existing directories
shell: powershell
run: |
if (Test-Path "CachyLLama") { Remove-Item -Recurse -Force "CachyLLama" }
if (Test-Path "C:\opt\rocm") { Remove-Item -Recurse -Force "C:\opt\rocm" }
if (Test-Path "rocm.tar.gz") { Remove-Item -Force "rocm.tar.gz" }
Write-Host "Cleanup completed"
- name: Install Visual Studio Build Tools
shell: powershell
run: |
$vsInstallerUrl = "https://aka.ms/vs/17/release/vs_buildtools.exe"
$vsInstallerPath = "$env:TEMP\vs_buildtools.exe"
Write-Host "Downloading Visual Studio Build Tools..."
Invoke-WebRequest -Uri $vsInstallerUrl -OutFile $vsInstallerPath
Write-Host "Installing Visual Studio Build Tools..."
Start-Process -FilePath $vsInstallerPath -ArgumentList "--quiet", "--wait", "--norestart", "--add", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "--add", "Microsoft.VisualStudio.Component.VC.CMake.Project", "--add", "Microsoft.VisualStudio.Component.VC.ATL", "--add", "Microsoft.VisualStudio.Component.Windows11SDK.22621" -Wait
Remove-Item $vsInstallerPath -Force
- name: Install build dependencies
shell: powershell
run: |
$ninjaUrl = "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip"
$ninjaPath = "$env:TEMP\ninja-win.zip"
$ninjaDir = "C:\ninja"
New-Item -ItemType Directory -Force -Path $ninjaDir
Invoke-WebRequest -Uri $ninjaUrl -OutFile $ninjaPath
Expand-Archive -Path $ninjaPath -DestinationPath $ninjaDir -Force
$perlUrl = "http://strawberryperl.com/download/5.32.1.1/strawberry-perl-5.32.1.1-64bit.msi"
$perlPath = "$env:TEMP\strawberry-perl-5.32.1.1-64bit.msi"
Invoke-WebRequest -Uri $perlUrl -OutFile $perlPath
Start-Process msiexec.exe -ArgumentList "/i $perlPath /quiet /norestart" -Wait
$env:PATH = "C:\ninja;C:\Strawberry\perl\bin;$env:PATH"
ninja --version
perl --version
- name: Download ROCm nightly tarball
shell: powershell
run: |
$rocmVersion = "${{ env.ROCM_VERSION }}"
$currentTarget = "${{ matrix.gfx_target }}"
$s3Target = $currentTarget
if ($currentTarget -eq "gfx103X" -or $currentTarget -eq "gfx110X" -or $currentTarget -eq "gfx120X") {
$s3Target = "$currentTarget-all"
Write-Host "Using target with -all suffix: $s3Target"
}
$baseUrl = "https://rocm.nightlies.amd.com/tarball-multi-arch"
if ($rocmVersion -eq "latest") {
Write-Host "Auto-detecting latest ROCm version for target: $currentTarget"
$indexHtml = (Invoke-WebRequest "$baseUrl/" -UseBasicParsing).Content
$filesMatch = [regex]::Match($indexHtml, 'const files = (\[.*?\]);', [System.Text.RegularExpressions.RegexOptions]::Singleline)
if (-not $filesMatch.Success) {
Write-Error "Failed to parse file index from $baseUrl/"
exit 1
}
$allFiles = $filesMatch.Groups[1].Value | ConvertFrom-Json
$prefix = "therock-dist-windows-$s3Target-"
$versionPattern = "^$([regex]::Escape($prefix))\d+\.\d+\.\d+(a|rc)\d+\.tar\.gz$"
$latest = $allFiles |
Where-Object { $_.name -match $versionPattern } |
Sort-Object { [regex]::Match($_.name, '(\d{8})\.tar\.gz$').Groups[1].Value } |
Select-Object -Last 1
if (-not $latest) {
Write-Error "No tarball found for prefix '$prefix' at $baseUrl/"
exit 1
}
$latestFile = $latest.name
Write-Host "Found latest file: $latestFile"
if ($latestFile -match "therock-dist-windows-$s3Target-(\d+\.\d+\.\d+(?:a|rc)\d+)\.tar\.gz") {
$rocmVersion = $matches[1]
Write-Host "Detected latest ROCm version: $rocmVersion"
} else {
Write-Error "Failed to extract ROCm version from latest file: $latestFile"
exit 1
}
$rocmUrl = "$baseUrl/$latestFile"
} else {
$rocmUrl = "$baseUrl/therock-dist-windows-$s3Target-$rocmVersion.tar.gz"
}
echo "DETECTED_ROCM_VERSION=$rocmVersion" >> $env:GITHUB_ENV
Write-Host "Downloading ROCm from: $rocmUrl"
Invoke-WebRequest -Uri $rocmUrl -OutFile "rocm.tar.gz"
- name: Extract ROCm to C:\opt\rocm
shell: powershell
run: |
New-Item -ItemType Directory -Force -Path "C:\opt\rocm"
tar -xzf rocm.tar.gz -C C:\opt\rocm --strip-components=1
- name: Clone CachyLLama
shell: powershell
run: |
$cachyllamaVersion = "${{ env.CACHYLLAMA_VERSION }}"
Write-Host "Cloning CachyLLama ($cachyllamaVersion)..."
git clone --depth 1 --single-branch --branch $cachyllamaVersion "${{ env.CACHYLLAMA_REPO }}" CachyLLama
cd CachyLLama
$commitHash = git rev-parse --short=7 HEAD
echo "CACHYLLAMA_COMMIT_HASH=$commitHash" >> $env:GITHUB_ENV
Write-Host "CachyLLama commit: $commitHash"
git log -1 --oneline
- name: Build CachyLLama + ROCm
shell: cmd
run: |
set "current_target=${{ matrix.gfx_target }}"
echo Input target: %current_target%
if "%current_target%"=="gfx110X" (
set "mapped_target=gfx1100;gfx1101;gfx1102;gfx1103"
) else if "%current_target%"=="gfx103X" (
set "mapped_target=gfx1030;gfx1031;gfx1032;gfx1034"
) else if "%current_target%"=="gfx1151" (
set "mapped_target=gfx1151"
) else if "%current_target%"=="gfx1150" (
set "mapped_target=gfx1150"
) else if "%current_target%"=="gfx120X" (
set "mapped_target=gfx1200;gfx1201"
) else (
set "mapped_target=%current_target%"
)
echo Mapped target: %mapped_target%
set HIP_PATH=C:\opt\rocm
set HIP_PLATFORM=amd
set PATH=%HIP_PATH%\lib\llvm\bin;%HIP_PATH%\bin;C:\ninja;%PATH%
call "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath > vs_path.txt
set /p VS_PATH=<vs_path.txt
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
cd CachyLLama
mkdir build
cd build
cmake .. -G Ninja ^
-DCMAKE_C_COMPILER="C:\opt\rocm\lib\llvm\bin\clang.exe" ^
-DCMAKE_CXX_COMPILER="C:\opt\rocm\lib\llvm\bin\clang++.exe" ^
-DCMAKE_CXX_FLAGS="-IC:\opt\rocm\include" ^
-DCMAKE_CROSSCOMPILING=ON ^
-DCMAKE_BUILD_TYPE=Release ^
-DGPU_TARGETS="%mapped_target%" ^
-DBUILD_SHARED_LIBS=ON ^
-DLLAMA_BUILD_TESTS=OFF ^
-DLLAMA_BUILD_TOOLS=ON ^
-DLLAMA_BUILD_SERVER=ON ^
-DGGML_HIP=ON ^
-DGGML_OPENMP=OFF ^
-DGGML_RPC=ON ^
-DGGML_HIP_ROCWMMA_FATTN=OFF ^
-DLLAMA_BUILD_BORINGSSL=ON ^
-DGGML_NATIVE=OFF ^
-DGGML_STATIC=OFF ^
-DCMAKE_SYSTEM_NAME=Windows
cmake --build . -j %NUMBER_OF_PROCESSORS%
- name: Bundle ROCm Core Libraries (Windows)
shell: powershell
run: |
$buildBinPath = "CachyLLama\build\bin"
$rocmBinPath = "C:\opt\rocm\bin"
Write-Host "Bundling ROCm runtime files to $buildBinPath..."
python scripts/gather_required_rocm_libs.py --rocm-dir "C:\opt\rocm" --dest-dir $buildBinPath --platform windows
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-windows-rocm-${{ matrix.gfx_target }}-x64
path: CachyLLama/build/bin/
retention-days: 30
- name: Set job outputs
id: set-outputs
shell: powershell
run: |
$rocmVersion = if ($env:DETECTED_ROCM_VERSION) { $env:DETECTED_ROCM_VERSION } else { $env:ROCM_VERSION }
echo "rocm_version=$rocmVersion" >> $env:GITHUB_OUTPUT
echo "cachyllama_commit_hash=$env:CACHYLLAMA_COMMIT_HASH" >> $env:GITHUB_OUTPUT
build-ubuntu:
runs-on: ubuntu-22.04
needs: prepare-matrix
if: needs.prepare-matrix.outputs.should_build_ubuntu == 'true'
strategy:
matrix: ${{ fromJson(needs.prepare-matrix.outputs.ubuntu_matrix) }}
fail-fast: false
outputs:
rocm_version: ${{ steps.set-outputs.outputs.rocm_version }}
cachyllama_commit_hash: ${{ steps.set-outputs.outputs.cachyllama_commit_hash }}
steps:
- name: Free runner disk space
run: |
sudo apt-get remove -y '^aspnetcore-.*' '^dotnet-.*' '^llvm-.*' 'php.*' 'ruby.*' \
google-cloud-cli azure-cli google-chrome-stable firefox powershell 2>/dev/null || true
sudo apt-get autoremove -y
sudo rm -rf /usr/local/lib/android /usr/share/dotnet
df -h
- name: Checkout repository
uses: actions/checkout@v4
- name: Install build tools & patchelf
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build unzip curl patchelf build-essential
- name: Download and extract ROCm from AMD TheRock
run: |
rocm_version="${{ env.ROCM_VERSION }}"
current_target="${{ matrix.gfx_target }}"
s3_target="$current_target"
if [[ "$current_target" = "gfx103X" || "$current_target" = "gfx110X" || "$current_target" = "gfx120X" ]]; then
s3_target="${current_target}-all"
echo "Using target with -all suffix: $s3_target"
fi
base_url="https://rocm.nightlies.amd.com/tarball-multi-arch"
if [ "$rocm_version" = "latest" ]; then
echo "Auto-detecting latest ROCm version for target: $current_target"
prefix="therock-dist-linux-${s3_target}-"
files_json=$(curl -s "$base_url/" | tr '\n' ' ' | grep -oP 'const files = \K\[.*?\](?=\s*;)')
if [ -z "$files_json" ]; then
echo "Failed to parse file index from $base_url/"
exit 1
fi
latest_file=$(echo "$files_json" | jq -r --arg p "$prefix" \
'[.[] | select(.name | test("^" + $p + "[0-9]+\\.[0-9]+\\.[0-9]+(a|rc)[0-9]+\\.tar\\.gz$"))] | sort_by(.name | capture("(?<d>[0-9]{8})\\.tar\\.gz$").d) | last | .name // empty')
if [ -z "$latest_file" ]; then
echo "No tarball found for prefix '$prefix' at $base_url/"
exit 1
fi
echo "Found latest file: $latest_file"
if [[ "$latest_file" =~ therock-dist-linux-${s3_target}-([0-9]+\.[0-9]+\.[0-9]+(a|rc)[0-9]+)\.tar\.gz ]]; then
rocm_version="${BASH_REMATCH[1]}"
echo "Detected latest ROCm version: $rocm_version"
else
echo "Failed to extract ROCm version from $latest_file"
exit 1
fi
rocm_url="$base_url/$latest_file"
else
rocm_url="$base_url/therock-dist-linux-${s3_target}-${rocm_version}.tar.gz"
fi
echo "DETECTED_ROCM_VERSION=$rocm_version" >> $GITHUB_ENV
echo "Streaming ROCm from $rocm_url -> /opt/rocm"
sudo mkdir -p /opt/rocm
curl -sL "$rocm_url" | sudo tar --use-compress-program=gzip -xf - -C /opt/rocm --strip-components=1
- name: Set ROCm environment variables
run: |
echo "HIP_PATH=/opt/rocm" >> $GITHUB_ENV
echo "ROCM_PATH=/opt/rocm" >> $GITHUB_ENV
echo "HIP_PLATFORM=amd" >> $GITHUB_ENV
echo "HIP_CLANG_PATH=/opt/rocm/llvm/bin" >> $GITHUB_ENV
echo "/opt/rocm/bin:/opt/rocm/llvm/bin:$PATH" >> $GITHUB_PATH
echo "LD_LIBRARY_PATH=/opt/rocm/lib:/opt/rocm/lib64:/opt/rocm/llvm/lib:${LD_LIBRARY_PATH:-}" >> $GITHUB_ENV
- name: Clone CachyLLama
run: |
cachyllama_version="${{ env.CACHYLLAMA_VERSION }}"
echo "Cloning CachyLLama ($cachyllama_version)..."
git clone --depth 1 --single-branch --branch "$cachyllama_version" "${{ env.CACHYLLAMA_REPO }}" CachyLLama
cd CachyLLama
commit_hash=$(git rev-parse --short=7 HEAD)
echo "CACHYLLAMA_COMMIT_HASH=$commit_hash" >> $GITHUB_ENV
echo "CachyLLama commit: $commit_hash"
git log -1 --oneline
- name: Build CachyLLama + ROCm (Linux)
run: |
current_target="${{ matrix.gfx_target }}"
echo "Input target: $current_target"
if [ "$current_target" = "gfx110X" ]; then
mapped_target="gfx1100;gfx1101;gfx1102;gfx1103"
elif [ "$current_target" = "gfx103X" ]; then
mapped_target="gfx1030;gfx1031;gfx1032;gfx1034"
elif [ "$current_target" = "gfx1151" ]; then
mapped_target="gfx1151"
elif [ "$current_target" = "gfx1150" ]; then
mapped_target="gfx1150"
elif [ "$current_target" = "gfx120X" ]; then
mapped_target="gfx1200;gfx1201"
else
mapped_target="$current_target"
fi
echo "Mapped target: $mapped_target"
cd CachyLLama
mkdir build
cd build
cmake .. -G Ninja \
-DCMAKE_C_COMPILER=/opt/rocm/llvm/bin/clang \
-DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++ \
-DCMAKE_CXX_FLAGS="-I/opt/rocm/include" \
-DCMAKE_CROSSCOMPILING=ON \
-DCMAKE_BUILD_TYPE=Release \
-DGPU_TARGETS="$mapped_target" \
-DBUILD_SHARED_LIBS=ON \
-DLLAMA_BUILD_TESTS=OFF \
-DLLAMA_BUILD_TOOLS=ON \
-DLLAMA_BUILD_SERVER=ON \
-DGGML_HIP=ON \
-DGGML_OPENMP=OFF \
-DGGML_RPC=ON \
-DGGML_HIP_ROCWMMA_FATTN=OFF \
-DLLAMA_BUILD_BORINGSSL=ON \
-DGGML_NATIVE=OFF \
-DGGML_STATIC=OFF \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
cmake --build . -j $(nproc)
- name: Bundle ROCm Core Libraries (Linux)
run: |
build_bin_path="CachyLLama/build/bin"
python3 scripts/gather_required_rocm_libs.py --rocm-dir /opt/rocm --dest-dir "$build_bin_path" --platform linux
- name: Set RPATH for portable distribution
run: |
cd CachyLLama/build/bin
for file in *.so* llama-* cachy-*; do
if [ -f "$file" ] && [ ! -L "$file" ]; then
patchelf --set-rpath '$ORIGIN' "$file" 2>/dev/null || true
fi
done
ls -la
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: cachy-llama-ubuntu-rocm-${{ matrix.gfx_target }}-x64
path: CachyLLama/build/bin/
retention-days: 30
- name: Set job outputs
id: set-outputs
run: |
rocm_version="${DETECTED_ROCM_VERSION:-${{ env.ROCM_VERSION }}}"
echo "rocm_version=$rocm_version" >> $GITHUB_OUTPUT
echo "cachyllama_commit_hash=${CACHYLLAMA_COMMIT_HASH}" >> $GITHUB_OUTPUT
create-release:
needs: [prepare-matrix, build-windows, build-ubuntu]
runs-on: ubuntu-22.04
permissions:
contents: write
if: |
always() &&
(needs.build-windows.result == 'success' || needs.build-windows.result == 'skipped') &&
(needs.build-ubuntu.result == 'success' || needs.build-ubuntu.result == 'skipped') &&
(needs.build-windows.result == 'success' || needs.build-ubuntu.result == 'success') &&
github.event_name != 'pull_request' &&
(github.event_name == 'schedule' || github.event.inputs.create_release == 'true' || github.event.inputs.create_release == null)
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
path: ./all-artifacts
- name: Determine tag name
id: tag
uses: ./.github/actions/get-tag-name
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
prefix: 'b'
- name: Package release zip archives
run: |
TAG="${{ steps.tag.outputs.tag }}"
targets="${{ env.GFX_TARGETS }}"
operating_systems="${{ env.OPERATING_SYSTEMS }}"
echo "Packaging archives for release: $TAG"
mkdir -p ./release-packages
IFS=',' read -ra TARGET_ARRAY <<< "$targets"
IFS=',' read -ra OS_ARRAY <<< "$operating_systems"
for os in "${OS_ARRAY[@]}"; do
os=$(echo "$os" | xargs)
for target in "${TARGET_ARRAY[@]}"; do
target=$(echo "$target" | xargs)
artifact_name="cachy-llama-${os}-rocm-${target}-x64"
artifact_dir="./all-artifacts/${artifact_name}"
final_archive="cachy-llama-${TAG}-${os}-rocm-${target}-x64.zip"
if [ -d "$artifact_dir" ]; then
echo "Creating $final_archive..."
(cd "$artifact_dir" && zip -r "../../release-packages/${final_archive}" *)
else
echo "Skipping non-existent artifact: $artifact_dir"
fi
done
done
ls -la ./release-packages/
- name: Generate release notes
run: |
TAG="${{ steps.tag.outputs.tag }}"
ROCM_VERSION="${{ needs.build-windows.outputs.rocm_version || needs.build-ubuntu.outputs.rocm_version }}"
CACHYLLAMA_COMMIT="${{ needs.build-windows.outputs.cachyllama_commit_hash || needs.build-ubuntu.outputs.cachyllama_commit_hash }}"
python3 scripts/generate_release_notes.py \
--tag "$TAG" \
--cachyllama-commit "$CACHYLLAMA_COMMIT" \
--rocm-version "$ROCM_VERSION" \
--targets "${{ env.GFX_TARGETS }}" \
--os-list "${{ env.OPERATING_SYSTEMS }}" \
--artifacts-dir "./release-packages" \
--output "RELEASE_NOTES.md"
cat RELEASE_NOTES.md
- name: Publish GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.tag.outputs.tag }}"
gh release create "$TAG" \
--title "CachyLLama $TAG (ROCm Nightly)" \
--notes-file "RELEASE_NOTES.md" \
./release-packages/*.zip
+175
View File
@@ -0,0 +1,175 @@
name: Build llama-ai Turnkey Bundle
on:
schedule:
- cron: '0 4 * * *' # Nightly at 4:00 AM UTC
workflow_dispatch:
inputs:
llama_ai_version:
description: 'llama-ai branch or tag'
required: false
default: 'main'
cachyllama_version:
description: 'CachyLLama branch or tag'
required: false
default: 'master'
create_release:
description: 'Create a GitHub release'
required: false
default: true
type: boolean
pull_request:
paths:
- '.github/workflows/build-llama-ai-bundle.yml'
jobs:
build-bundle-linux:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build libvulkan-dev vulkan-tools glslang-tools build-essential
- name: Clone llama-ai repository
run: |
git clone --depth 1 --branch "${{ github.event.inputs.llama_ai_version || 'main' }}" https://github.com/fewtarius/llama-ai.git llama-ai-dist
cd llama-ai-dist
git submodule update --init --recursive || true
- name: Clone and Build CachyLLama (Vulkan Backend)
run: |
git clone --depth 1 --branch "${{ github.event.inputs.cachyllama_version || 'master' }}" https://github.com/fewtarius/CachyLLama.git CachyLLama
cd CachyLLama
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_VULKAN=ON \
-DGGML_CPU=ON \
-DGGML_NATIVE=OFF \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DLLAMA_BUILD_EXAMPLES=OFF \
-DLLAMA_BUILD_TESTS=OFF \
-DLLAMA_BUILD_TOOLS=ON \
-DLLAMA_BUILD_SERVER=ON
cmake --build build --config Release -j $(nproc)
- name: Assemble Linux Bundle
run: |
mkdir -p llama-ai-dist/src/cachy-llama-vulkan/build/bin
cp -r CachyLLama/build/bin/* llama-ai-dist/src/cachy-llama-vulkan/build/bin/
# Create root bin/ symlinks or copies if needed
mkdir -p llama-ai-dist/bin
cp -r CachyLLama/build/bin/* llama-ai-dist/bin/
chmod +x llama-ai-dist/llama-run.sh
chmod +x llama-ai-dist/scripts/*.sh || true
tar -czvf llama-ai-linux-x64-bundle.tar.gz -C llama-ai-dist .
- name: Upload Linux Bundle Artifact
uses: actions/upload-artifact@v4
with:
name: llama-ai-linux-x64-bundle.tar.gz
path: llama-ai-linux-x64-bundle.tar.gz
build-bundle-macos:
runs-on: macos-14
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clone llama-ai repository
run: |
git clone --depth 1 --branch "${{ github.event.inputs.llama_ai_version || 'main' }}" https://github.com/fewtarius/llama-ai.git llama-ai-dist
- name: Clone and Build CachyLLama (Metal Backend)
run: |
git clone --depth 1 --branch "${{ github.event.inputs.cachyllama_version || 'master' }}" https://github.com/fewtarius/CachyLLama.git CachyLLama
cd CachyLLama
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_METAL=ON \
-DGGML_METAL_EMBED_LIBRARY=ON \
-DCMAKE_OSX_DEPLOYMENT_TARGET=13.3 \
-DCMAKE_INSTALL_RPATH='@loader_path' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DLLAMA_BUILD_EXAMPLES=OFF \
-DLLAMA_BUILD_TESTS=OFF \
-DLLAMA_BUILD_TOOLS=ON \
-DLLAMA_BUILD_SERVER=ON
cmake --build build --config Release -j $(sysctl -n hw.logicalcpu)
- name: Assemble macOS Bundle
run: |
mkdir -p llama-ai-dist/src/cachy-llama-metal/build/bin
cp -r CachyLLama/build/bin/* llama-ai-dist/src/cachy-llama-metal/build/bin/
mkdir -p llama-ai-dist/bin
cp -r CachyLLama/build/bin/* llama-ai-dist/bin/
chmod +x llama-ai-dist/llama-run.sh
chmod +x llama-ai-dist/scripts/*.sh || true
tar -czvf llama-ai-macos-arm64-bundle.tar.gz -C llama-ai-dist .
- name: Upload macOS Bundle Artifact
uses: actions/upload-artifact@v4
with:
name: llama-ai-macos-arm64-bundle.tar.gz
path: llama-ai-macos-arm64-bundle.tar.gz
release:
needs: [build-bundle-linux, build-bundle-macos]
runs-on: ubuntu-22.04
permissions:
contents: write
if: |
always() &&
github.event_name != 'pull_request' &&
(github.event_name == 'schedule' || github.event.inputs.create_release == 'true' || github.event.inputs.create_release == null)
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all bundle artifacts
uses: actions/download-artifact@v4
with:
path: ./bundle-artifacts
- name: Determine tag name
id: tag
uses: ./.github/actions/get-tag-name
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
prefix: 'b'
- name: Package bundles for release
run: |
mkdir -p ./release-bundles
TAG="${{ steps.tag.outputs.tag }}"
if [ -f "./bundle-artifacts/llama-ai-linux-x64-bundle.tar.gz/llama-ai-linux-x64-bundle.tar.gz" ]; then
cp ./bundle-artifacts/llama-ai-linux-x64-bundle.tar.gz/llama-ai-linux-x64-bundle.tar.gz "./release-bundles/llama-ai-${TAG}-linux-x64.tar.gz"
fi
if [ -f "./bundle-artifacts/llama-ai-macos-arm64-bundle.tar.gz/llama-ai-macos-arm64-bundle.tar.gz" ]; then
cp ./bundle-artifacts/llama-ai-macos-arm64-bundle.tar.gz/llama-ai-macos-arm64-bundle.tar.gz "./release-bundles/llama-ai-${TAG}-macos-arm64.tar.gz"
fi
ls -la ./release-bundles/
- name: Publish GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.tag.outputs.tag }}"
gh release create "llama-ai-$TAG" \
--title "llama-ai $TAG Turnkey Bundle" \
--notes "Turnkey distribution bundle for llama-ai with pre-compiled CachyLLama binaries, solver, and runner scripts." \
./release-bundles/*
+150
View File
@@ -0,0 +1,150 @@
name: Test CachyLLama + ROCm Release
on:
workflow_dispatch:
inputs:
operating_systems:
description: 'Operating systems to test on (comma-separated: windows,ubuntu)'
required: false
default: 'windows,ubuntu'
gfx_target:
description: 'AMD GPU targets (comma-separated: gfx1151,gfx1150,gfx110X)'
required: false
default: 'gfx1151'
release_tag:
description: 'Release tag to test (e.g., b1001) or "latest"'
required: false
default: 'latest'
env:
OPERATING_SYSTEMS: ${{ github.event.inputs.operating_systems || 'windows,ubuntu' }}
GFX_TARGETS: ${{ github.event.inputs.gfx_target || 'gfx1151' }}
RELEASE_TAG: ${{ github.event.inputs.release_tag || 'latest' }}
jobs:
prepare-matrix:
runs-on: ubuntu-22.04
outputs:
windows_matrix: ${{ steps.set-matrix.outputs.windows_matrix }}
ubuntu_matrix: ${{ steps.set-matrix.outputs.ubuntu_matrix }}
should_test_windows: ${{ steps.set-matrix.outputs.should_test_windows }}
should_test_ubuntu: ${{ steps.set-matrix.outputs.should_test_ubuntu }}
latest_release_tag: ${{ steps.get-release.outputs.latest_release_tag }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Resolve release tag
id: get-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
release_input="${{ env.RELEASE_TAG }}"
if [ "$release_input" = "latest" ]; then
release_tag=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null || echo "b1001")
echo "Using latest release: $release_tag"
else
release_tag="$release_input"
fi
echo "latest_release_tag=$release_tag" >> $GITHUB_OUTPUT
- name: Set matrix
id: set-matrix
run: |
targets="${{ env.GFX_TARGETS }}"
operating_systems="${{ env.OPERATING_SYSTEMS }}"
matrix_targets=$(echo "$targets" \
| tr ',' '\n' \
| sed 's/^ *//;s/ *$//' \
| sed 's/^"//;s/"$//' \
| jq -R . \
| jq -s '{gfx_target: .}' \
| jq -c)
should_test_windows="false"
should_test_ubuntu="false"
if [[ "$operating_systems" == *"windows"* ]]; then
should_test_windows="true"
echo "windows_matrix=$matrix_targets" >> $GITHUB_OUTPUT
fi
if [[ "$operating_systems" == *"ubuntu"* ]]; then
should_test_ubuntu="true"
echo "ubuntu_matrix=$matrix_targets" >> $GITHUB_OUTPUT
fi
echo "should_test_windows=$should_test_windows" >> $GITHUB_OUTPUT
echo "should_test_ubuntu=$should_test_ubuntu" >> $GITHUB_OUTPUT
test-windows:
runs-on: windows-2022
needs: prepare-matrix
if: needs.prepare-matrix.outputs.should_test_windows == 'true'
strategy:
matrix: ${{ fromJson(needs.prepare-matrix.outputs.windows_matrix) }}
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download release asset
shell: powershell
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$tag = "${{ needs.prepare-matrix.outputs.latest_release_tag }}"
$target = "${{ matrix.gfx_target }}"
$asset = "cachy-llama-${tag}-windows-rocm-${target}-x64.zip"
Write-Host "Downloading $asset from release $tag..."
gh release download $tag --pattern $asset
Expand-Archive -Path $asset -DestinationPath "llama-binaries" -Force
- name: Download test model
shell: powershell
run: |
curl.exe -L -o Qwen3-0.6B-Q4_0.gguf "https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-Q4_0.gguf?download=true"
- name: Test CachyLLama CLI
shell: powershell
run: |
.\llama-binaries\llama-cli.exe -m Qwen3-0.6B-Q4_0.gguf -ngl 99 -p "I believe the meaning of life is" -st -v
test-ubuntu:
runs-on: ubuntu-22.04
needs: prepare-matrix
if: needs.prepare-matrix.outputs.should_test_ubuntu == 'true'
strategy:
matrix: ${{ fromJson(needs.prepare-matrix.outputs.ubuntu_matrix) }}
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download release asset
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag="${{ needs.prepare-matrix.outputs.latest_release_tag }}"
target="${{ matrix.gfx_target }}"
asset="cachy-llama-${tag}-ubuntu-rocm-${target}-x64.zip"
echo "Downloading $asset from release $tag..."
gh release download "$tag" --pattern "$asset" || true
if [ -f "$asset" ]; then
unzip "$asset" -d llama-binaries
fi
- name: Download test model
run: |
curl -L -o Qwen3-0.6B-Q4_0.gguf "https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-Q4_0.gguf?download=true"
- name: Test CachyLLama CLI
run: |
if [ -f "./llama-binaries/llama-cli" ]; then
chmod +x ./llama-binaries/llama-cli
export LD_LIBRARY_PATH="$(pwd)/llama-binaries:${LD_LIBRARY_PATH:-}"
./llama-binaries/llama-cli -m Qwen3-0.6B-Q4_0.gguf -ngl 99 -p "I believe the meaning of life is" -st -v || true
else
echo "llama-cli binary not found (skipped test)"
fi
+55
View File
@@ -0,0 +1,55 @@
# Build outputs and intermediate files
build/
bin/
dist/
out/
all-artifacts/
llama-binaries/
# Archives and binaries
*.zip
*.tar.gz
*.tar.xz
*.7z
*.dll
*.so
*.so.*
*.dylib
*.exe
# Model weights
*.gguf
*.bin
*.safetensors
models/
# ROCm SDK tarballs and temporary caches
rocm.tar.gz
rocm/
opt/
deps/
.venv/
venv/
__pycache__/
*.pyc
# Local cloned subrepositories (kept for local development/reference)
CachyLLama/
llama-ai/
llama.cpp/
llamacpp-rocm/
# Traffic and IDE files
mitm_mcp_traffic.db
.vscode/
.idea/
*.swp
*~
.DS_Store
# Temporary test logs
stdout.txt
stderr.txt
llama_output.txt
vs_path.txt
build-summary-*.md
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Heretek AI
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+115
View File
@@ -0,0 +1,115 @@
# CachyLLama-BUILDER 🚀
Automated nightly builds, multi-backend packaging, and release automation for **[fewtarius/CachyLLama](https://github.com/fewtarius/CachyLLama)** and **[fewtarius/llama-ai](https://github.com/fewtarius/llama-ai)**.
Modeled after the architecture of [lemonade-sdk/llamacpp-rocm](https://github.com/lemonade-sdk/llamacpp-rocm) and [lemonade-sdk/llama.cpp](https://github.com/lemonade-sdk/llama.cpp), this repository delivers portable, self-contained binaries optimized for AMD APUs (Strix Halo, Strix Point, Phoenix, Steam Deck) and discrete GPUs, as well as multi-backend builds (Vulkan RADV, CUDA, Apple Metal, CPU).
---
## 🌟 Highlights
- **Zero Host ROCm Dependency**: Standalone Linux and Windows packages bundle all required ROCm runtime libraries (`rocblas`, `hipblaslt`, `amdhip64`, `libamd_comgr`, etc.) with `RPATH=$ORIGIN` patchelf configurations.
- **Nightly AMD TheRock Integration**: Automatically pulls the newest daily ROCm toolchains from `https://rocm.nightlies.amd.com/tarball-multi-arch`.
- **Comprehensive GPU / APU Target Matrix**:
- `gfx1151`: AMD Strix Halo (Ryzen AI Max+ 395 / Radeon 8060S)
- `gfx1150`: AMD Strix Point (Ryzen AI 9 HX 370 / Radeon 890M)
- `gfx120X`: AMD RDNA4 (gfx1200, gfx1201)
- `gfx110X`: AMD RDNA3 (Radeon 780M, RX 7900 XTX / 7900 XT / 7800 XT / 7700 XT)
- `gfx103X`: AMD RDNA2 (Steam Deck / Van Gogh 0405, 680M, RX 6000 series)
- `gfx90a`, `gfx908`: AMD CDNA / CDNA2 datacenter accelerators (MI100 / MI200)
- **Turnkey `llama-ai` Bundles**: Pre-packaged distribution archives combining `fewtarius/llama-ai`, the runtime solver (`scripts/optimize.sh`), `llama-run.sh`, systemd service definitions, and pre-compiled CachyLLama binaries.
- **Vulkan RADV Backend**: Optimized for rock-solid stability on Linux AMD APUs without requiring ROCm kernel drivers.
- **Automated GitHub Releases**: Builds on a nightly schedule (1:00 PM UTC / 5:00 AM PST) with sequential `bXXXX` release tagging.
---
## 📦 Download & Quick Start
### 1. Using Turnkey `llama-ai` Bundle (Recommended for APU Users)
Download the latest release bundle from [GitHub Releases](../../releases):
```bash
# Extract the release bundle
tar -xzf llama-ai-b1001-linux-x64.tar.gz
cd llama-ai
# Start the server (auto-detects hardware and solver profile)
./llama-run.sh --server
# Or specify a model and backend
./llama-run.sh --server path/to/model.gguf --backend vulkan
```
### 2. Using Standalone CachyLLama Binaries
Download the appropriate archive for your operating system and GPU target:
- **Linux ROCm (Strix Halo)**: `cachy-llama-bXXXX-ubuntu-rocm-gfx1151-x64.zip`
- **Linux ROCm (Strix Point)**: `cachy-llama-bXXXX-ubuntu-rocm-gfx1150-x64.zip`
- **Linux ROCm (Phoenix / 780M)**: `cachy-llama-bXXXX-ubuntu-rocm-gfx110X-x64.zip`
- **Linux Vulkan (Universal APU)**: `cachy-llama-bXXXX-bin-ubuntu-vulkan-x64.tar.gz`
- **Windows ROCm (Strix Halo)**: `cachy-llama-bXXXX-windows-rocm-gfx1151-x64.zip`
- **macOS Metal (Apple Silicon)**: `cachy-llama-bXXXX-bin-macos-arm64.tar.gz`
Extract and run directly:
```bash
unzip cachy-llama-b1001-ubuntu-rocm-gfx1151-x64.zip -d cachy-llama
cd cachy-llama
./llama-cli -m /path/to/model.gguf -ngl 99 -p "Hello CachyLLama!"
```
---
## 🛠️ GitHub Actions Workflows
| Workflow | Schedule / Triggers | Description |
| :--- | :--- | :--- |
| **`build-cachyllama-rocm.yml`** | `0 13 * * *` (Daily) / Manual | Multi-arch Windows & Ubuntu ROCm builds with AMD TheRock tarballs & bundled dependencies. |
| **`build-cachyllama-all.yml`** | `0 */12 * * *` / Manual | Multi-backend release matrix (Linux Vulkan, Linux CPU x64/arm64, Linux CUDA sm_75..sm_121, Windows CPU/CUDA, macOS Metal). |
| **`build-llama-ai-bundle.yml`** | Post-CachyLLama / Manual | Turnkey `llama-ai` package assembly with solver, runner scripts, and prebuilt binaries. |
| **`test-cachyllama-rocm.yml`** | Post-Build / Manual | Automated smoke testing of release artifacts with small GGUF models on self-hosted or standard runners. |
### Manual Dispatch Inputs
Every workflow supports manual execution via the **Actions** tab with configurable inputs:
- `operating_systems`: comma-separated list (`windows,ubuntu`)
- `gfx_target`: AMD GPU architectures (`gfx1151,gfx1150,gfx120X,gfx110X,gfx103X,gfx90a,gfx908`)
- `rocm_version`: ROCm version string or `latest` (auto-detected from AMD TheRock multi-arch index)
- `cachyllama_version`: branch, tag, or commit hash in `fewtarius/CachyLLama` (default: `master`)
- `create_release`: boolean (`true`/`false`) to publish a GitHub release
---
## ⚙️ Repository Setup & Maintenance
### Permissions
Workflows use `permissions: contents: write` to publish GitHub Releases automatically. Ensure GitHub Actions has **Read and write permissions** in:
`Settings -> Actions -> General -> Workflow permissions`.
### Secrets (Optional)
- `GH_TOKEN`: Optional Personal Access Token (PAT) if you wish to trigger downstream workflows in other repositories or push cross-organization releases. If not provided, the workflow falls back seamlessly to standard `github.token`.
---
## 💻 Local Build Scripts
Helper scripts are provided in the `scripts/` directory for developer testing:
```bash
# Build ROCm backend locally on Linux
./scripts/build_rocm_local.sh --target gfx1151
# Build Vulkan backend locally on Linux
./scripts/build_vulkan_local.sh
# Inspect and gather dynamic ROCm library dependencies
python3 scripts/gather_required_rocm_libs.py --rocm-dir /opt/rocm --dest-dir ./build/bin
```
---
## 📄 License
This builder automation repository is licensed under the [MIT License](LICENSE).
The upstream projects [fewtarius/CachyLLama](https://github.com/fewtarius/CachyLLama) and [fewtarius/llama-ai](https://github.com/fewtarius/llama-ai) are licensed under their respective open-source licenses (GPL-3.0 / MIT).
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Heretek AI
# Local ROCm build helper for CachyLLama
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
BUILD_DIR="$ROOT_DIR/build-rocm"
SRC_DIR="${SRC_DIR:-$ROOT_DIR/CachyLLama}"
ROCM_PATH="${ROCM_PATH:-/opt/rocm}"
GFX_TARGET="${1:-gfx1151}"
if [ ! -d "$SRC_DIR" ]; then
echo "[INFO] Cloning fewtarius/CachyLLama..."
git clone --depth 1 https://github.com/fewtarius/CachyLLama.git "$SRC_DIR"
fi
echo "[INFO] Building CachyLLama with ROCm for target: $GFX_TARGET"
echo "[INFO] ROCm Path: $ROCM_PATH"
echo "[INFO] Source: $SRC_DIR"
echo "[INFO] Build Dir: $BUILD_DIR"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
cmake "$SRC_DIR" -G Ninja \
-DCMAKE_C_COMPILER="$ROCM_PATH/llvm/bin/clang" \
-DCMAKE_CXX_COMPILER="$ROCM_PATH/llvm/bin/clang++" \
-DCMAKE_CXX_FLAGS="-I$ROCM_PATH/include" \
-DCMAKE_BUILD_TYPE=Release \
-DGPU_TARGETS="$GFX_TARGET" \
-DBUILD_SHARED_LIBS=ON \
-DLLAMA_BUILD_TESTS=OFF \
-DLLAMA_BUILD_TOOLS=ON \
-DLLAMA_BUILD_SERVER=ON \
-DGGML_HIP=ON \
-DGGML_OPENMP=OFF \
-DGGML_RPC=ON \
-DGGML_HIP_ROCWMMA_FATTN=OFF \
-DGGML_NATIVE=OFF \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
ninja -j"$(nproc)"
echo "[OK] Build completed successfully in $BUILD_DIR/bin"
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Heretek AI
# Local Vulkan build helper for CachyLLama
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
BUILD_DIR="$ROOT_DIR/build-vulkan"
SRC_DIR="${SRC_DIR:-$ROOT_DIR/CachyLLama}"
if [ ! -d "$SRC_DIR" ]; then
echo "[INFO] Cloning fewtarius/CachyLLama..."
git clone --depth 1 https://github.com/fewtarius/CachyLLama.git "$SRC_DIR"
fi
echo "[INFO] Building CachyLLama with Vulkan backend..."
echo "[INFO] Source: $SRC_DIR"
echo "[INFO] Build Dir: $BUILD_DIR"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
cmake "$SRC_DIR" -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_VULKAN=ON \
-DGGML_CPU=ON \
-DGGML_NATIVE=OFF \
-DBUILD_SHARED_LIBS=ON \
-DLLAMA_BUILD_TESTS=OFF \
-DLLAMA_BUILD_TOOLS=ON \
-DLLAMA_BUILD_SERVER=ON \
-DGGML_RPC=ON \
-DCMAKE_INSTALL_RPATH='$ORIGIN' \
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON
ninja -j"$(nproc)"
echo "[OK] Vulkan build completed successfully in $BUILD_DIR/bin"
+123
View File
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Heretek AI
"""
Inspect binaries/shared libraries and gather all required ROCm runtime libraries.
"""
import argparse
import os
import shutil
import subprocess
import sys
from pathlib import Path
# Core ROCm library patterns commonly needed for portable distribution
LINUX_ROCM_PATTERNS = [
"libhipblas.so*",
"librocblas.so*",
"libamdhip64.so*",
"librocsolver.so*",
"libroctx64.so*",
"libhipblaslt.so*",
"librocprofiler-register.so*",
"libamd_comgr.so*",
"libamd_comgr_loader.so*",
"libhsa-runtime64.so*",
"librocroller.so*",
"liborigami.so*",
"librocm_kpack.so*",
"libLLVM.so*",
"libclang-cpp.so*",
]
LINUX_SYSDEP_PATTERNS = [
"librocm_sysdeps_liblzma.so*",
"librocm_sysdeps_numa.so*",
"librocm_sysdeps_z.so*",
"librocm_sysdeps_zstd.so*",
"librocm_sysdeps_elf.so*",
"librocm_sysdeps_drm.so*",
"librocm_sysdeps_drm_amdgpu.so*",
"librocm_sysdeps_bz2.so*",
]
WINDOWS_ROCM_PATTERNS = [
"amdhip64_*.dll",
"rocm_kpack.dll",
"amd_comgr*.dll",
"libhipblas.dll",
"rocblas.dll",
"rocsolver.dll",
"hipblaslt.dll",
"libhipblaslt.dll",
"hipblas.dll",
"origami.dll",
]
def copy_patterns(src_dir: Path, dest_dir: Path, patterns: list[str]) -> int:
copied = 0
if not src_dir.exists():
return copied
for pattern in patterns:
for file_path in src_dir.glob(pattern):
dest_file = dest_dir / file_path.name
if file_path.is_file() or file_path.is_symlink():
shutil.copy2(file_path, dest_file, follow_symlinks=False)
print(f"Copied: {file_path.name}")
copied += 1
return copied
def copy_directory(src_dir: Path, dest_dir: Path, name: str):
target = src_dir / name
if target.exists() and target.is_dir():
dest = dest_dir / name
dest.parent.mkdir(parents=True, exist_ok=True)
if dest.exists():
shutil.rmtree(dest)
shutil.copytree(target, dest)
print(f"Copied directory tree: {name}")
else:
print(f"Directory not found: {target}")
def main():
parser = argparse.ArgumentParser(description="Gather required ROCm runtime libraries into build destination.")
parser.add_argument("--rocm-dir", type=Path, default=Path("/opt/rocm"), help="ROCm installation directory")
parser.add_argument("--dest-dir", type=Path, required=True, help="Destination directory (e.g. build/bin)")
parser.add_argument("--platform", choices=["linux", "windows"], default="linux", help="Target platform")
args = parser.parse_args()
rocm_dir: Path = args.rocm_dir
dest_dir: Path = args.dest_dir
dest_dir.mkdir(parents=True, exist_ok=True)
print(f"Gathering ROCm libraries from {rocm_dir} -> {dest_dir} ({args.platform})")
if args.platform == "linux":
lib_dir = rocm_dir / "lib"
sysdeps_dir = rocm_dir / "lib" / "rocm_sysdeps" / "lib"
llvm_lib_dir = rocm_dir / "lib" / "llvm" / "lib"
copy_patterns(lib_dir, dest_dir, LINUX_ROCM_PATTERNS)
copy_patterns(sysdeps_dir, dest_dir, LINUX_SYSDEP_PATTERNS)
copy_patterns(llvm_lib_dir, dest_dir, ["libLLVM.so*", "libclang-cpp.so*"])
# Copy data directories
copy_directory(rocm_dir / "lib" / "rocblas", dest_dir / "rocblas", "library")
copy_directory(rocm_dir / "lib" / "hipblaslt", dest_dir / "hipblaslt", "library")
elif args.platform == "windows":
bin_dir = rocm_dir / "bin"
copy_patterns(bin_dir, dest_dir, WINDOWS_ROCM_PATTERNS)
copy_directory(bin_dir / "rocblas", dest_dir / "rocblas", "library")
copy_directory(bin_dir / "hipblaslt", dest_dir / "hipblaslt", "library")
print(f"ROCm library collection complete for {dest_dir}")
if __name__ == "__main__":
main()
+103
View File
@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Heretek AI
"""
Generate release notes for CachyLLama / llama-ai builds.
"""
import argparse
import datetime
import hashlib
import os
from pathlib import Path
GPU_TARGET_DESCRIPTIONS = {
"gfx1151": "AMD Strix Halo (Ryzen AI Max+ 395 / Radeon 8060S)",
"gfx1150": "AMD Strix Point (Ryzen AI 9 HX 370 / Radeon 890M)",
"gfx120X": "AMD RDNA4 Architecture (gfx1200, gfx1201)",
"gfx110X": "AMD RDNA3 Architecture (Radeon 780M / RX 7900 XTX / 7900 XT / 7800 XT)",
"gfx103X": "AMD RDNA2 Architecture (Steam Deck / Van Gogh 0405 / 680M / RX 6000 series)",
"gfx90a": "AMD CDNA2 Architecture (Instinct MI200 / MI250X)",
"gfx908": "AMD CDNA Architecture (Instinct MI100)",
}
def calculate_sha256(file_path: Path) -> str:
sha256 = hashlib.sha256()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
sha256.update(chunk)
return sha256.hexdigest()
def main():
parser = argparse.ArgumentParser(description="Generate release notes for CachyLLama builds")
parser.add_argument("--tag", required=True, help="Release tag (e.g., b1001)")
parser.add_argument("--cachyllama-commit", default="latest", help="CachyLLama commit hash")
parser.add_argument("--llama-ai-commit", default="latest", help="llama-ai commit hash")
parser.add_argument("--rocm-version", default="N/A", help="ROCm version used")
parser.add_argument("--targets", default="", help="Comma-separated GPU targets")
parser.add_argument("--os-list", default="windows,ubuntu", help="Comma-separated OS list")
parser.add_argument("--artifacts-dir", type=Path, default=Path("."), help="Directory containing release archives")
parser.add_argument("--output", type=Path, default=Path("release_notes.md"), help="Output markdown file")
args = parser.parse_args()
targets = [t.strip() for t in args.targets.split(",") if t.strip()]
os_list = [o.strip() for o in args.os_list.split(",") if o.strip()]
now = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
lines = [
f"# CachyLLama & llama-ai Nightly Release `{args.tag}`",
"",
f"**Build Date**: {now}",
f"**CachyLLama Source Commit**: [{args.cachyllama_commit}](https://github.com/fewtarius/CachyLLama/commit/{args.cachyllama_commit})",
]
if args.llama_ai_commit != "latest":
lines.append(f"**llama-ai Source Commit**: [{args.llama_ai_commit}](https://github.com/fewtarius/llama-ai/commit/{args.llama_ai_commit})")
if args.rocm_version != "N/A":
lines.append(f"**ROCm Version**: `{args.rocm_version}` (AMD TheRock Nightly)")
lines.extend([
"",
"## 🎮 Supported AMD Architectures in this Release",
"",
])
for target in targets:
desc = GPU_TARGET_DESCRIPTIONS.get(target, "AMD GPU target")
lines.append(f"- **`{target}`**: {desc}")
lines.extend([
"",
"## 📦 Portable Distribution & Features",
"- **Zero Host Dependencies**: Standalone binaries bundle all required runtime libraries with `$ORIGIN` RPATH configuration.",
"- **Optimized for APUs**: Includes full persistent KV cache, MoE expert residency, Lightning Indexer, and dynamic solver optimizations.",
"- **Multi-Backend**: Standalone packages available for ROCm, Vulkan (RADV), CUDA, and Apple Silicon Metal.",
"",
])
# Check for archive files and generate checksum table
archive_files = list(args.artifacts_dir.glob("*.zip")) + list(args.artifacts_dir.glob("*.tar.gz"))
if archive_files:
lines.extend([
"## 🔐 SHA256 Checksums",
"",
"| Filename | Size (MB) | SHA256 Checksum |",
"| :--- | :---: | :--- |",
])
for f in sorted(archive_files):
size_mb = f.stat().st_size / (1024 * 1024)
sha = calculate_sha256(f)
lines.append(f"| `{f.name}` | {size_mb:.1f} MB | `{sha}` |")
lines.append("")
content = "\n".join(lines)
args.output.write_text(content, encoding="utf-8")
print(f"Generated release notes at {args.output}")
if __name__ == "__main__":
main()