mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-07 16:37:57 +02:00
Compare commits
26
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5150132b9a | ||
|
|
74a7c897f0 | ||
|
|
6a1a922d26 | ||
|
|
4d9176092d | ||
|
|
cd8cdf397d | ||
|
|
427291b5b3 | ||
|
|
85d5703a3b | ||
|
|
1548a240e3 | ||
|
|
4acf4a4cb8 | ||
|
|
8b4b3558f1 | ||
|
|
1863ac0333 | ||
|
|
49c0dc82b8 | ||
|
|
5266f24da7 | ||
|
|
64a155d242 | ||
|
|
163a40796f | ||
|
|
8f83678fd8 | ||
|
|
86b351fd64 | ||
|
|
d509cb1e86 | ||
|
|
4cbe8b070b | ||
|
|
24f5bf8a41 | ||
|
|
a529af96e2 | ||
|
|
38521ec33f | ||
|
|
0ef4d560e1 | ||
|
|
c390d0abbc | ||
|
|
832fd6f174 | ||
|
|
9a4843cf2f |
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Got an idea?
|
||||
url: https://github.com/ggml-org/llama.cpp/discussions/categories/ideas
|
||||
|
||||
@@ -50,8 +50,16 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: apple-arm64
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: apple-arm64
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
@@ -67,6 +75,18 @@ jobs:
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=13.3
|
||||
time cmake --build build --config Release -j $(sysctl -n hw.logicalcpu)
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: apple-arm64
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Check for leaks
|
||||
run: |
|
||||
cmd=(./build/bin/test-thread-safety -hf ggml-org/gemma-3-270m-qat-GGUF -ngl 99 -p "$(printf 'hello %.0s' {1..128})" -n 16 -c 512 -ub 32 -np 2 -t 2 -lv 1)
|
||||
@@ -80,16 +100,6 @@ jobs:
|
||||
cd build
|
||||
ctest -L main -E "test-llama-archs" --verbose --timeout 900
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: apple-arm64
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
macos-latest-x64:
|
||||
runs-on: macos-15-intel
|
||||
|
||||
@@ -102,8 +112,16 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: apple-x64
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: apple-x64
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
@@ -120,22 +138,24 @@ jobs:
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=13.3
|
||||
time cmake --build build --config Release -j $(sysctl -n hw.logicalcpu)
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: apple-x64
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Test
|
||||
id: cmake_test
|
||||
run: |
|
||||
cd build
|
||||
ctest -L main --verbose --timeout 900
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: apple-x64
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
macos-latest-ios-xcode:
|
||||
runs-on: macos-latest
|
||||
|
||||
|
||||
@@ -65,8 +65,7 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: cpu-${{ matrix.os }}
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: Build Dependencies
|
||||
id: build_depends
|
||||
@@ -91,6 +90,15 @@ jobs:
|
||||
python3 -m pip install --upgrade pip setuptools
|
||||
pip3 install ./gguf-py
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: cpu-${{ matrix.os }}
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
run: |
|
||||
@@ -100,6 +108,18 @@ jobs:
|
||||
-DGGML_RPC=ON
|
||||
time cmake --build build --config Release -j $(nproc)
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: cpu-${{ matrix.os }}
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Test
|
||||
id: cmake_test
|
||||
run: |
|
||||
@@ -117,18 +137,6 @@ jobs:
|
||||
./bin/llama-convert-llama2c-to-ggml --copy-vocab-from-model ./tok512.bin --llama2c-model stories260K.bin --llama2c-output-model stories260K.gguf
|
||||
./bin/llama-completion -m stories260K.gguf -p "One day, Lily met a Shoggoth" -n 500 -c 256
|
||||
|
||||
# note: real deletion only on push to master (same condition as the ccache save),
|
||||
# dry-run otherwise (the token is read-only on PRs from forks)
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: cpu-${{ matrix.os }}
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
windows:
|
||||
name: windows / ${{ matrix.build }}
|
||||
runs-on: windows-2025
|
||||
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: cuda-ubuntu-24.04-cuda
|
||||
folder: llama.cpp
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: cuda-ubuntu-22.04-hip
|
||||
folder: llama.cpp
|
||||
@@ -167,7 +167,7 @@ jobs:
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: cuda-ubuntu-22.04-musa
|
||||
folder: llama.cpp
|
||||
|
||||
@@ -32,8 +32,8 @@ env:
|
||||
LLAMA_ARG_LOG_COLORS: 1
|
||||
LLAMA_ARG_LOG_PREFIX: 1
|
||||
LLAMA_ARG_LOG_TIMESTAMPS: 1
|
||||
# TODO: fix and re-enable the `test-llama-archs` and `test-recurrent-state-rollback`
|
||||
CTEST_EXCLUDE: "test-llama-archs|^test-recurrent-state-rollback"
|
||||
# TODO: fix failing tests on OpenVINO backend
|
||||
CTEST_EXCLUDE: "test-llama-archs|^test-recurrent-state-|test-backend-ops|test-save-load-state"
|
||||
|
||||
jobs:
|
||||
ubuntu-24-openvino:
|
||||
|
||||
@@ -78,8 +78,16 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: sycl-ubuntu-24-${{ matrix.build }}
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: sycl-ubuntu-24-${{ matrix.build }}
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
@@ -96,15 +104,17 @@ jobs:
|
||||
-DGGML_SYCL_F16=${{ matrix.fp16 }}
|
||||
time cmake --build build --config Release -j $(nproc)
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: sycl-ubuntu-24-${{ matrix.build }}
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
windows-latest-sycl:
|
||||
runs-on: windows-2022
|
||||
|
||||
@@ -57,8 +57,16 @@ jobs:
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-arm
|
||||
variant: ccache
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-arm
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Configure
|
||||
id: cmake_configure
|
||||
@@ -73,15 +81,17 @@ jobs:
|
||||
run: |
|
||||
time cmake --build build -j $(nproc)
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-arm
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
ubuntu-llvmpipe:
|
||||
runs-on: ubuntu-24.04
|
||||
@@ -115,8 +125,16 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-llvmpipe
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-llvmpipe
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
@@ -127,6 +145,18 @@ jobs:
|
||||
-DGGML_VULKAN=ON
|
||||
cmake --build build --config Release -j $(nproc)
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-llvmpipe
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Test
|
||||
id: cmake_test
|
||||
run: |
|
||||
@@ -138,16 +168,6 @@ jobs:
|
||||
# test-backend-ops is too slow on llvmpipe, skip it
|
||||
ctest -L main -E test-backend-ops --verbose --timeout 900
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: vulkan-ubuntu-24.04-llvmpipe
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
windows:
|
||||
runs-on: windows-2025
|
||||
|
||||
|
||||
@@ -57,8 +57,7 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04-arm-wasm
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: Install Emscripten
|
||||
run: |
|
||||
@@ -76,6 +75,15 @@ jobs:
|
||||
"https://github.com/google/dawn/releases/download/${DAWN_TAG}/${EMDAWN_PKG}"
|
||||
unzip emdawn.zip
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04-arm-wasm
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build WASM WebGPU
|
||||
run: |
|
||||
source emsdk/emsdk_env.sh
|
||||
@@ -89,12 +97,14 @@ jobs:
|
||||
|
||||
time cmake --build build-wasm --config Release --target test-backend-ops -j $(nproc)
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04-arm-wasm
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
@@ -72,8 +72,7 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: webgpu-macos-latest
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: Dawn Dependency
|
||||
id: dawn-depends
|
||||
@@ -88,6 +87,15 @@ jobs:
|
||||
mkdir dawn
|
||||
tar -xvf artifact.tar.gz -C dawn --strip-components=1
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: webgpu-macos-latest
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
run: |
|
||||
@@ -95,22 +103,24 @@ jobs:
|
||||
cmake -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DGGML_WEBGPU=ON -DGGML_METAL=OFF -DGGML_BLAS=OFF
|
||||
time cmake --build build --config Release -j $(sysctl -n hw.logicalcpu)
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: webgpu-macos-latest
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Test
|
||||
id: cmake_test
|
||||
run: |
|
||||
cd build
|
||||
ctest -L main --verbose --timeout 900
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: webgpu-macos-latest
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
ubuntu:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -123,8 +133,7 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: Dependencies
|
||||
id: depends
|
||||
@@ -148,6 +157,15 @@ jobs:
|
||||
mkdir dawn
|
||||
tar -xvf artifact.tar.gz -C dawn --strip-components=1
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
run: |
|
||||
@@ -156,6 +174,18 @@ jobs:
|
||||
-DGGML_WEBGPU=ON
|
||||
time cmake --build build --config Release -j $(nproc)
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Test
|
||||
id: cmake_test
|
||||
run: |
|
||||
@@ -163,13 +193,3 @@ jobs:
|
||||
# This is using llvmpipe and runs slower than other backends
|
||||
# test-backend-ops is too slow on llvmpipe, skip it
|
||||
ctest -L main -E test-backend-ops --verbose --timeout 900
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: webgpu-ubuntu-24.04
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
@@ -49,14 +49,22 @@ jobs:
|
||||
id: depends
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential git cmake rocblas-dev hipblas-dev libssl-dev python3
|
||||
sudo apt-get install -y build-essential git cmake rocblas-dev hipblas-dev libssl-dev python3 python3-venv python3-pip jq
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: hip-quality-check-ubuntu-22.04
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: hip-quality-check-ubuntu-22.04
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build with Werror
|
||||
id: cmake_build
|
||||
@@ -85,12 +93,14 @@ jobs:
|
||||
make -j $(nproc) 2>&1 | tee metrics.log | grep -v 'Rpass-analysis=kernel-resource-usage\|remark:\|^$'
|
||||
python3 ../scripts/hip/gcn-cdna-vgpr-check.py metrics.log
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: hip-quality-check-ubuntu-22.04
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
@@ -83,8 +83,16 @@ jobs:
|
||||
uses: ggml-org/ccache-action@v1.2.24
|
||||
with:
|
||||
key: server-ubuntu-24.04-arm
|
||||
evict-old-files: 1d
|
||||
save: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
save: false
|
||||
|
||||
- name: ccache-buckets-restore
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CI }}
|
||||
with:
|
||||
key: server-ubuntu-24.04-arm
|
||||
folder: llama.cpp
|
||||
hf_bucket: ggml-org/cache
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
@@ -93,6 +101,18 @@ jobs:
|
||||
-DGGML_SCHED_NO_REALLOC=ON
|
||||
cmake --build build --config Release -j $(nproc) --target llama-server
|
||||
|
||||
- name: ccache-buckets-save
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
||||
uses: ./.github/actions/ccache-buckets
|
||||
env:
|
||||
HF_TOKEN: ${{ secrets.HF_TOKEN_CACHE_OUTPUT }}
|
||||
with:
|
||||
key: server-ubuntu-24.04-arm
|
||||
folder: llama.cpp
|
||||
evict-old-files: 1d
|
||||
hf_bucket: ggml-org/cache
|
||||
save: true
|
||||
|
||||
- name: Python setup
|
||||
id: setup_python
|
||||
uses: actions/setup-python@v6
|
||||
@@ -128,16 +148,6 @@ jobs:
|
||||
export LLAMA_ARG_BACKEND_SAMPLING=1
|
||||
SLOW_TESTS=1 ./tests.sh
|
||||
|
||||
- name: ccache-clear
|
||||
uses: ./.github/actions/ccache-clear
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
key: server-ubuntu-24.04-arm
|
||||
older: 5m
|
||||
min: 1
|
||||
dry-run: ${{ github.event_name != 'push' || github.ref != 'refs/heads/master' }}
|
||||
|
||||
windows:
|
||||
runs-on: windows-2025
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# date: Tue Aug 18 14:32:43 EEST 2026
|
||||
# date: Fri Sep 4 10:06:46 EEST 2026
|
||||
# this file is auto-generated by scripts/gen-authors.sh
|
||||
|
||||
Нияз Гарифзянов <112617865+garrnizon@users.noreply.github.com>
|
||||
@@ -46,6 +46,7 @@ Abhijit Ramesh <abhijitramesh2k@gmail.com>
|
||||
abhijitb11 <113058133+abhijitb11@users.noreply.github.com>
|
||||
Abhilash Majumder <30946547+abhilash1910@users.noreply.github.com>
|
||||
Abhinay Krishna <abhinaykrishna60@gmail.com>
|
||||
Abhiram <78226909+geckguy@users.noreply.github.com>
|
||||
Abhishek Gopinath K <31348521+overtunned@users.noreply.github.com>
|
||||
abotsis <github@bots.is>
|
||||
Abraham Gonzalez <theabecaster0@gmail.com>
|
||||
@@ -87,6 +88,7 @@ akleine <alb.kleine@gmx.de>
|
||||
Al G <toasting@gmail.com>
|
||||
Al Mochkin <14274697+amochkin@users.noreply.github.com>
|
||||
Alan Gray <agray3@users.noreply.github.com>
|
||||
Alan Tseng <alanhc.tseng1999@gmail.com>
|
||||
Alawode Oluwandabira <dabiraalawode@yahoo.com>
|
||||
Albert Jin <albert.jin@gmail.com>
|
||||
Alberto <57916483+albbus-stack@users.noreply.github.com>
|
||||
@@ -136,7 +138,9 @@ alonfaraj <alonfaraj@gmail.com>
|
||||
AlpinDale <52078762+AlpinDale@users.noreply.github.com>
|
||||
alwqx <kenan3015@gmail.com>
|
||||
Aman <amangupta052@gmail.com>
|
||||
Aman Chadha(IVIXMMI) <79802170+ac-mmi@users.noreply.github.com>
|
||||
Aman Gupta <amangupta052@gmail.com>
|
||||
Aman Karki <itsamankarki@gmail.com>
|
||||
amd-dwang <dong.wang@amd.com>
|
||||
amd-lalithnc <lalithnc@amd.com>
|
||||
Amir <amir_zia@outlook.com>
|
||||
@@ -187,6 +191,7 @@ Anton Mitkov <anton.mitkov@codeplay.com>
|
||||
Antonis Makropoulos <benuix@gmail.com>
|
||||
Anudit Nagar <nagaranudit@gmail.com>
|
||||
Anuj Attri <anujattri01@gmail.com>
|
||||
anujj <ajalota@nvidia.com>
|
||||
anzz1 <anzz1@live.com>
|
||||
Aparna M P <aparmp@qti.qualcomm.com>
|
||||
Aparna M P <quic_aparmp@quicinc.com>
|
||||
@@ -196,6 +201,7 @@ arch-btw <57669023+arch-btw@users.noreply.github.com>
|
||||
arcrank <arcrank@gmail.com>
|
||||
ardfork <134447697+ardfork@users.noreply.github.com>
|
||||
Arik Poznanski <arikpoz@users.noreply.github.com>
|
||||
Aritro Bandyopadhyay <71339004+AriBandyo@users.noreply.github.com>
|
||||
arlo-phoenix <140345165+arlo-phoenix@users.noreply.github.com>
|
||||
Armen Kaleshian <kriation@users.noreply.github.com>
|
||||
Arsen Arutunan <58118221+limloop@users.noreply.github.com>
|
||||
@@ -230,6 +236,7 @@ bandoti <141645996+bandoti@users.noreply.github.com>
|
||||
Bar Haim <barvhaim@gmail.com>
|
||||
BarfingLemurs <128182951+BarfingLemurs@users.noreply.github.com>
|
||||
Bart Louwers <bart.louwers@gmail.com>
|
||||
Bartosz Taudul <wolf@nereid.pl>
|
||||
Bartowski <3266127+bartowski1182@users.noreply.github.com>
|
||||
Bartowski <ckealty1182@gmail.com>
|
||||
Bas Nijholt <basnijholt@gmail.com>
|
||||
@@ -277,6 +284,7 @@ Bono Lv <lvscar@users.noreply.github.com>
|
||||
Borislav Stanimirov <b.stanimirov@abv.bg>
|
||||
Borislav Stanimirov <b@ibob.bg>
|
||||
Bowen Han <fancycode@gmail.com>
|
||||
Brad Smith <1472326+infinitewarp@users.noreply.github.com>
|
||||
Branden Butler <bwtbutler@hotmail.com>
|
||||
Brandon Squizzato <35474886+bsquizz@users.noreply.github.com>
|
||||
Brian <mofosyne@gmail.com>
|
||||
@@ -287,6 +295,7 @@ Bryan Honof <bryanhonof@gmail.com>
|
||||
bryanSwk <93190252+bryanSwk@users.noreply.github.com>
|
||||
bsilvereagle <bsilvereagle@users.noreply.github.com>
|
||||
bssrdf <merlintiger@hotmail.com>
|
||||
Buğra Özgürsoy <13810383+ozgursoy@users.noreply.github.com>
|
||||
byte-6174 <88070277+byte-6174@users.noreply.github.com>
|
||||
Caleb DeLeeuw <143902425+SolshineCode@users.noreply.github.com>
|
||||
Calvin Laurenson <calvin@laurenson.dev>
|
||||
@@ -326,6 +335,7 @@ Chenguang Li <757486878@qq.com>
|
||||
Chenguang Li <87689256+noemotiovon@users.noreply.github.com>
|
||||
Chipmunk <101038159+CHIPMUNK-T0T@users.noreply.github.com>
|
||||
chiranko <96988916+chiranko@users.noreply.github.com>
|
||||
Chris Danis <cdanis@gmail.com>
|
||||
Chris Elrod <elrodc@gmail.com>
|
||||
Chris Kuehl <ckuehl@ckuehl.me>
|
||||
Chris Lee <clee@mg8.org>
|
||||
@@ -356,6 +366,7 @@ clyang <clyang@clyang.net>
|
||||
cmdr2 <secondary.cmdr2@gmail.com>
|
||||
cmdr2 <shashank.shekhar.global@gmail.com>
|
||||
cocktailpeanut <121128867+cocktailpeanut@users.noreply.github.com>
|
||||
codemonkey <441345965@qq.com>
|
||||
codezjx <code.zjx@gmail.com>
|
||||
coezbek <c.oezbek@gmail.com>
|
||||
comex <comexk@gmail.com>
|
||||
@@ -367,6 +378,8 @@ Copilot <198982749+Copilot@users.noreply.github.com>
|
||||
Corentin REGAL <corentin.regal@gmail.com>
|
||||
cphlipot <9103367+cphlipot@users.noreply.github.com>
|
||||
cpumaxx <163466046+cpumaxx@users.noreply.github.com>
|
||||
cqderek <cqderek@gmail.com>
|
||||
cqderek <cqiang@qti.qualcomm.com>
|
||||
crasm <crasm@git.vczf.net>
|
||||
crasm <crasm@git.vczf.us>
|
||||
crat0z <11581854+crat0z@users.noreply.github.com>
|
||||
@@ -427,6 +440,7 @@ DavidKorczynski <david@adalogics.com>
|
||||
davidrhodus <david@vacovideo.com>
|
||||
Dawid Potocki <github@dawidpotocki.com>
|
||||
Dawid Wysocki <62249621+TortillaZHawaii@users.noreply.github.com>
|
||||
Daya Adianto <addianto@users.noreply.github.com>
|
||||
ddh0 <chemist-mulches-39@icloud.com>
|
||||
ddh0 <dylanhalladay02@icloud.com>
|
||||
ddpasa <112642920+ddpasa@users.noreply.github.com>
|
||||
@@ -463,6 +477,7 @@ Dmytro Romanov <casteldazur@gmail.com>
|
||||
Dobri Danchev <12420863+danchev@users.noreply.github.com>
|
||||
DocShotgun <126566557+DocShotgun@users.noreply.github.com>
|
||||
Doctor Shotgun <126566557+DocShotgun@users.noreply.github.com>
|
||||
Dominik Pantaleoni <95251853+dpantaleoni@users.noreply.github.com>
|
||||
Don Mahurin <dmahurin@users.noreply.github.com>
|
||||
Dong Won Kim <63934649+ddwkim@users.noreply.github.com>
|
||||
Donghyeon Jeong <54725479+djeong20@users.noreply.github.com>
|
||||
@@ -504,6 +519,7 @@ Emmanuel Ferdman <emmanuelferdman@gmail.com>
|
||||
Emreerdog <34742675+Emreerdog@users.noreply.github.com>
|
||||
Engininja2 <139037756+Engininja2@users.noreply.github.com>
|
||||
Equim <sayaka@ekyu.moe>
|
||||
Eric A Stalee <87948564+Eric-A-Stalee@users.noreply.github.com>
|
||||
Eric Curtin <ecurtin@redhat.com>
|
||||
Eric Curtin <eric.curtin@docker.com>
|
||||
Eric Curtin <ericcurtin17@gmail.com>
|
||||
@@ -519,6 +535,7 @@ Esko Toivonen <eskot98@gmail.com>
|
||||
Ethan Turner <eturner64@gmail.com>
|
||||
Ettore Di Giacinto <mudler@users.noreply.github.com>
|
||||
EugeoSynthesisThirtyTwo <gabriel.dhimoila@gmail.com>
|
||||
Eurekatic <eurekatic@eurekatic.eu>
|
||||
Evan Huus <eapache@gmail.com>
|
||||
Evan Jones <evan.q.jones@gmail.com>
|
||||
Evan Miller <emmiller@gmail.com>
|
||||
@@ -677,6 +694,7 @@ HimariO <dsfhe49854@gmail.com>
|
||||
hipudding <huafengchun@gmail.com>
|
||||
Hitesh Chopra <34310832+hiteshchopra11@users.noreply.github.com>
|
||||
hksdpc255 <43977088+hksdpc255@users.noreply.github.com>
|
||||
hmirin <hmirin@users.noreply.github.com>
|
||||
hmscider <201289679+hmscider@users.noreply.github.com>
|
||||
Hoang Nguyen <hugo53@users.noreply.github.com>
|
||||
hoangmit <hoangmit@users.noreply.github.com>
|
||||
@@ -701,6 +719,7 @@ Huawei Lin <huaweilin.cs@gmail.com>
|
||||
Hugo <hugo@whynothugo.nl>
|
||||
Hugo Roussel <hugo.rous@gmail.com>
|
||||
Huifeng Ou <79071290+ho2103@users.noreply.github.com>
|
||||
HumerousGorgon <31957201+HumerousGorgon@users.noreply.github.com>
|
||||
hutli <6594598+hutli@users.noreply.github.com>
|
||||
hutli <hutli@hutli.hu>
|
||||
hutli <jensstaermose@hotmail.com>
|
||||
@@ -738,12 +757,15 @@ intelmatt <61025942+intelmatt@users.noreply.github.com>
|
||||
iohub <rickyang.pro@gmail.com>
|
||||
Ionoclast Laboratories <brigham@ionoclast.com>
|
||||
iron <lizhenneng@gmail.com>
|
||||
Isaac <34376531+init-22@users.noreply.github.com>
|
||||
Isaac McFadyen <isaac@imcf.me>
|
||||
IsaacDynamo <61521674+IsaacDynamo@users.noreply.github.com>
|
||||
Ishaan Gandhi <Ishaangandhi@gmail.com>
|
||||
iSma <ismail.senhaji@gmail.com>
|
||||
Ismail <115064057+AlrIsmail@users.noreply.github.com>
|
||||
issixx <46835150+issixx@users.noreply.github.com>
|
||||
itsnotoger <19309683+itsnotoger@users.noreply.github.com>
|
||||
itterative <190138728+itterative@users.noreply.github.com>
|
||||
Ivan <nekotekina@gmail.com>
|
||||
Ivan Chikish <nekotekina@gmail.com>
|
||||
Ivan Filipov <159561759+vanaka11@users.noreply.github.com>
|
||||
@@ -768,6 +790,7 @@ Jakkala Mahesh <155058658+MaheshJakkala@users.noreply.github.com>
|
||||
Jakub N <jakubniemczyk97@gmail.com>
|
||||
JamePeng <jame_peng@sina.com>
|
||||
James A Capozzoli <157492257+jac-jim@users.noreply.github.com>
|
||||
James Francis <6763899+JamesFranc@users.noreply.github.com>
|
||||
James O'Leary <65884233+jpohhhh@users.noreply.github.com>
|
||||
James Reynolds <magnusviri@users.noreply.github.com>
|
||||
jameswu2014 <545426914@qq.com>
|
||||
@@ -798,6 +821,7 @@ Jed Fox <git@jedfox.com>
|
||||
Jeff Bolz <jbolz@nvidia.com>
|
||||
Jeffrey Morgan <jmorganca@gmail.com>
|
||||
Jeffrey Quesnelle <emozilla@nousresearch.com>
|
||||
Jeremie Miller <jeremie.miller@gmail.com>
|
||||
Jeremy Demeule <jdemeule@users.noreply.github.com>
|
||||
Jeremy Rand <244188+JeremyRand@users.noreply.github.com>
|
||||
Jeroen Mostert <jeroen.mostert@cm.com>
|
||||
@@ -809,6 +833,7 @@ Jesse Jojo Johnson <williamsaintgeorge@gmail.com>
|
||||
Jesse LaRose <jesse@taey.ai>
|
||||
Jesse Posner <jesse.posner@gmail.com>
|
||||
Jesus Talavera <145992175+jesus-talavera-ibm@users.noreply.github.com>
|
||||
Jetson Tan <tanzongyouyi@outlook.com>
|
||||
Jett Janiak <jettjaniak@gmail.com>
|
||||
Jeximo <jeximo@gmail.com>
|
||||
JFLFY2255 <JFLFY2255@163.com>
|
||||
@@ -825,6 +850,7 @@ Jie Fu (傅杰) <jiefu@tencent.com>
|
||||
jiez <373447296@qq.com>
|
||||
Jillis ter Hove <j.terhove@gmail.com>
|
||||
Jim Wu <jimw567@users.noreply.github.com>
|
||||
Jingxin (Philip) Li <philipaslee@gmail.com>
|
||||
Jinwoo Jeong <33892306+williamjeong2@users.noreply.github.com>
|
||||
Jinyang He <hejinyang@loongson.cn>
|
||||
jinzihao <jinzihao1996@gmail.com>
|
||||
@@ -850,11 +876,13 @@ John Balis <phobossystems@gmail.com>
|
||||
John Bean <113509988+johnbean393@users.noreply.github.com>
|
||||
John Eismeier <42679190+jeis4wpi@users.noreply.github.com>
|
||||
John Smith <67539080+kingsidelee@users.noreply.github.com>
|
||||
John-Henry Lim <42513874+Interpause@users.noreply.github.com>
|
||||
Johnathan Craig Maudlin <13183098+jcmdln@users.noreply.github.com>
|
||||
JohnnyB <jboero@users.noreply.github.com>
|
||||
johnson442 <56517414+johnson442@users.noreply.github.com>
|
||||
jojorne <jojorne@users.noreply.github.com>
|
||||
jon-chuang <9093549+jon-chuang@users.noreply.github.com>
|
||||
Jonas J <111707981+John-194@users.noreply.github.com>
|
||||
Jonas Jankaitis <111707981+John-194@users.noreply.github.com>
|
||||
Jonas Wunderlich <32615971+jonas-w@users.noreply.github.com>
|
||||
Jonathan <47618606+jbuchananr@users.noreply.github.com>
|
||||
@@ -924,6 +952,7 @@ Karsten Weiss <knweiss@gmail.com>
|
||||
Karthick <j.karthic2004@gmail.com>
|
||||
Karthik Kumar Viswanathan <195178+guilt@users.noreply.github.com>
|
||||
Karthik Sethuraman <k.seth1993@gmail.com>
|
||||
Kartik Gulia <kgulia@nvidia.com>
|
||||
Kartik Sirohi <99896785+sirohikartik@users.noreply.github.com>
|
||||
Kashif Rasul <kashif.rasul@gmail.com>
|
||||
KASR <karim.asrih@gmail.com>
|
||||
@@ -931,6 +960,7 @@ Kasumi <90275229+kasumi-1@users.noreply.github.com>
|
||||
Katostrofik <georgiopapairo@gmail.com>
|
||||
katsu560 <118887472+katsu560@users.noreply.github.com>
|
||||
Kawrakow <48489457+ikawrakow@users.noreply.github.com>
|
||||
kbenkhaled <khalilbenkhaled01@gmail.com>
|
||||
kchro3 <62481661+kchro3@users.noreply.github.com>
|
||||
kdkd <2569413+kdkd@users.noreply.github.com>
|
||||
Keiichi Tabata <keiichi.tabata@outlook.com>
|
||||
@@ -939,6 +969,7 @@ Kenvix ⭐ <kenvixzure@live.com>
|
||||
Kerfuffle <44031344+KerfuffleV2@users.noreply.github.com>
|
||||
Kevin Gibbons <bakkot@gmail.com>
|
||||
Kevin Hannon <kehannon@redhat.com>
|
||||
Kevin Hopper <93635715+kh0pper@users.noreply.github.com>
|
||||
Kevin Ji <1146876+kevinji@users.noreply.github.com>
|
||||
Kevin Kwok <antimatter15@gmail.com>
|
||||
Kevin Liu <4396kevinliu@gmail.com>
|
||||
@@ -964,12 +995,14 @@ Konstantin Herud <konstantin.herud@denkbares.com>
|
||||
Konstantin Zhuravlyov <konstantin.zhuravlyov@amd.com>
|
||||
Krishna Sridhar <99914379+srikris-sridhar@users.noreply.github.com>
|
||||
krystiancha <krystian@krystianch.com>
|
||||
krzsztf <krzysztof@witkowscy.org>
|
||||
kubawoo <k-wach@o2.pl>
|
||||
kumaal <44551860+kumaal@users.noreply.github.com>
|
||||
kunal-vaishnavi <115581922+kunal-vaishnavi@users.noreply.github.com>
|
||||
kunnis <kunnis@users.noreply.github.com>
|
||||
Kunshang Ji <kunshang.ji@intel.com>
|
||||
kuronekosaiko <EvanChanJ@163.com>
|
||||
kurquhar <kurquhar@qti.qualcomm.com>
|
||||
Kusha Gharahi <3326002+kushagharahi@users.noreply.github.com>
|
||||
kustaaya <58045274+kustaaya@users.noreply.github.com>
|
||||
kuvaus <22169537+kuvaus@users.noreply.github.com>
|
||||
@@ -981,6 +1014,7 @@ Kyle Liang <liangmanlai@gmail.com>
|
||||
Kyle Mistele <kyle@mistele.com>
|
||||
KyleHagy <59183061+KyleHagy@users.noreply.github.com>
|
||||
Kylin <56434533+KyL0N@users.noreply.github.com>
|
||||
Kyozzz <1147385157@qq.com>
|
||||
l-austenfeld <53152202+l-austenfeld@users.noreply.github.com>
|
||||
l3utterfly <gc.pthzfoldr@gmail.com>
|
||||
l8bloom <l8bloomapi@gmail.com>
|
||||
@@ -992,6 +1026,7 @@ Lars Sonchocky-Helldorf <lars.sonchocky-helldorf@hamburg.de>
|
||||
las7 <98077186+las7@users.noreply.github.com>
|
||||
Lasse Lauwerys <65569591+Iemand005@users.noreply.github.com>
|
||||
Laura <Tijntje_7@msn.com>
|
||||
Laurent Zuijdwijk <laurent.zuijdwijk@gmail.com>
|
||||
Law Po Ying <30721578+yingying0906@users.noreply.github.com>
|
||||
lcy <lcy0321@users.noreply.github.com>
|
||||
ldwang <ftgreat@163.com>
|
||||
@@ -1039,6 +1074,8 @@ Ludovic Henry <git@ludovic.dev>
|
||||
Ludovic Henry <ludovic@rivosinc.com>
|
||||
Lukas Straub <lukasstraub2@web.de>
|
||||
Łukasz Ślusarczyk <112692748+lslusarczyk@users.noreply.github.com>
|
||||
Lukasz Stolcman <4583553+lstolcman@users.noreply.github.com>
|
||||
LunalFresh <165352784+LunalFresh@users.noreply.github.com>
|
||||
Luo Tian <lt@basecity.com>
|
||||
luoyu-intel <yu.luo@intel.com>
|
||||
luyhcsu <110711054+luyhcsu@users.noreply.github.com>
|
||||
@@ -1054,6 +1091,7 @@ Maarten ter Huurne <maarten@treewalker.org>
|
||||
Maciej Lisowski <39798354+MaciejDromin@users.noreply.github.com>
|
||||
Mack Straight <eiz@users.noreply.github.com>
|
||||
maddes8cht <55592906+maddes8cht@users.noreply.github.com>
|
||||
Mads Marquart <mads@marquart.dk>
|
||||
Maël Kerbiriou <m431.kerbiriou@gmail.com>
|
||||
MaggotHATE <clay1326@gmail.com>
|
||||
MagicExists <106458387+gugugiyu@users.noreply.github.com>
|
||||
@@ -1215,6 +1253,8 @@ Naco Siren <naco-siren@users.noreply.github.com>
|
||||
Nam D. Tran <42194884+namtranase@users.noreply.github.com>
|
||||
nanahi <130121847+na-na-hi@users.noreply.github.com>
|
||||
Nathan Epstein <nate2@umbc.edu>
|
||||
Nathan Wilson <67372905+Nathanw1014@users.noreply.github.com>
|
||||
Nathanw1014 <67372905+Nathanw1014@users.noreply.github.com>
|
||||
Natsu <chino@hotococoa.moe>
|
||||
Nauful Shaikh <nauful@gmail.com>
|
||||
NawafAlansari <72708095+NawafAlansari@users.noreply.github.com>
|
||||
@@ -1237,6 +1277,7 @@ niansa/tuxifan <tuxifan@posteo.de>
|
||||
Nicholai Tukanov <nicholaitukanov@gmail.com>
|
||||
Nicholas Sparks <157740354+nisparks@users.noreply.github.com>
|
||||
Nick <0x0b4ac@gmail.com>
|
||||
Nick Farrell <nick.farrell@aiven.io>
|
||||
nick huang <nickhuang99@hotmail.com>
|
||||
Nick Lafleur <55208706+nicklafleur@users.noreply.github.com>
|
||||
Nick Towle <ntowle@gmail.com>
|
||||
@@ -1259,6 +1300,7 @@ NikolaiLyssogor <59844691+NikolaiLyssogor@users.noreply.github.com>
|
||||
Nikolaos Pothitos <pothitos@di.uoa.gr>
|
||||
Nikolas <127742645+nneubacher@users.noreply.github.com>
|
||||
Nikolay Popov <131475237+npopov-vst@users.noreply.github.com>
|
||||
Nils Gladitz <nilsgladitz@gmail.com>
|
||||
Nindaleth <Nindaleth@users.noreply.github.com>
|
||||
ningshanwutuobang <ningshanwutuobang@gmail.com>
|
||||
Noah <99681487+NoahOksuz@users.noreply.github.com>
|
||||
@@ -1355,6 +1397,7 @@ Pop Flamingo <trevor.annedenise@icloud.com>
|
||||
postmasters <namnguyen@google.com>
|
||||
Pouya <PooyaGhahramanian@Gmail.com>
|
||||
pqnet <119850+pqnet@users.noreply.github.com>
|
||||
Prabhsimran Singh <pskrunner14@gmail.com>
|
||||
Prabod <prabod@maincode.com>
|
||||
Prajwal B Mehendarkar <prajwal.b.mehendarkar@ibm.com>
|
||||
Pranav Dhinakar <pdhinaka@qti.qualcomm.com>
|
||||
@@ -1378,6 +1421,7 @@ qouoq <qouoq@fastmail.com>
|
||||
Qu Zongfu <43257352+yancaoweidaode@users.noreply.github.com>
|
||||
quei <56998528+quei4r@users.noreply.github.com>
|
||||
Quentin Bramas <quentin.bramas@gmail.com>
|
||||
QuintinShaw <github@xyt.email>
|
||||
QuintinShaw <yx6f20@soton.ac.uk>
|
||||
qunash <anzoria@gmail.com>
|
||||
quyentonndbs <raynaedgar8677@outlook.com>
|
||||
@@ -1462,6 +1506,7 @@ robertomeroni <150194833+robertomeroni@users.noreply.github.com>
|
||||
Robey Holderith <robey@flaminglunchbox.net>
|
||||
Robin Davidsson <40024429+R-Dson@users.noreply.github.com>
|
||||
Robyn <robyngraf@users.noreply.github.com>
|
||||
Rock Chen <rockchen.tw@gmail.com>
|
||||
Rőczey Barnabás <31726601+An0nie@users.noreply.github.com>
|
||||
RodriMora <bullerwins@gmail.com>
|
||||
Roger Chen <chenrui@gmail.com>
|
||||
@@ -1499,17 +1544,21 @@ runfuture <runfuture@users.noreply.github.com>
|
||||
RunningLeon <maningsheng@sensetime.com>
|
||||
RunningLeon <mnsheng@yeah.net>
|
||||
Russyyds <161207317+Russyyds@users.noreply.github.com>
|
||||
Ryan C <ryan5rdx@users.noreply.github.com>
|
||||
Ryan Goulden <percontation@gmail.com>
|
||||
Ryan Landay <rlanday@gmail.com>
|
||||
Ryan Mangeno <160974989+ryan-mangeno@users.noreply.github.com>
|
||||
Ryder Wishart <ryderwishart@gmail.com>
|
||||
Ryuei <louixs@users.noreply.github.com>
|
||||
s-goto-11 <206795233+s-goto-11@users.noreply.github.com>
|
||||
s0mecode <213953308+s0mecode@users.noreply.github.com>
|
||||
s8322 <s0527684199@gmail.com>
|
||||
Saad Ali <NIXKnight@users.noreply.github.com>
|
||||
Saba Fallah <10401143+sfallah@users.noreply.github.com>
|
||||
Saba Fallah <sabafallah@gmail.com>
|
||||
Sachin Desai <smdesai@gmail.com>
|
||||
Sachin Sharma <sachin@zettabolt.com>
|
||||
Safi Ullah <safiullah.3915@gmail.com>
|
||||
safranowith <bsh155762@gmail.com>
|
||||
SakuraUmi <yukinon244@gmail.com>
|
||||
Salvador E. Tropea <stropea@inti.gob.ar>
|
||||
@@ -1552,6 +1601,7 @@ Sergey Alirzaev <l29ah@riseup.net>
|
||||
Sergey Alirzaev <zl29ah@gmail.com>
|
||||
Sergey Fedorov <vital.had@gmail.com>
|
||||
Sergey Malinin <sergmalinin@gmail.com>
|
||||
Sergey Sklyarov <sergey.sklyarov@gmail.com>
|
||||
Sergio López <slp@redhat.com>
|
||||
Sergio López <slp@sinrega.org>
|
||||
Sergiu <8598216+mzsergiu@users.noreply.github.com>
|
||||
@@ -1582,11 +1632,13 @@ Shawn Gu <shawngu@qti.qualcomm.com>
|
||||
Shawn yang <137684499+Yangxiaoz@users.noreply.github.com>
|
||||
Shelby Jenkins <47464908+ShelbyJenkins@users.noreply.github.com>
|
||||
Sheldon Robinson <sheldon.robinson@live.com>
|
||||
Shenghan Yang <ysharke@sjtu.edu.cn>
|
||||
shibe2 <shibe@tuta.io>
|
||||
Shijie <821898965@qq.com>
|
||||
Shin-myoung-serp <relent95@naver.com>
|
||||
Shintarou Okada <kokuzen@gmail.com>
|
||||
shivamkumard-ctrl <shivamkumard@nvidia.com>
|
||||
Shobhit <sobhit.me@gmail.com>
|
||||
Shouyu <65317431+joeldushouyu@users.noreply.github.com>
|
||||
Shouzheng Liu <61452103+lshzh-ww@users.noreply.github.com>
|
||||
Shouzheng Liu <lshzh.hi@gmail.com>
|
||||
@@ -1607,6 +1659,7 @@ Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
|
||||
Sigbjørn Skjæret <sigbjorn.skjaeret@scala.com>
|
||||
simevo <github@simevo.com>
|
||||
Simon Redman <simon@ergotech.com>
|
||||
Simon Teixidor <simon@flaskpost.me>
|
||||
Simon Willison <swillison@gmail.com>
|
||||
simon886212 <37953122+simon886212@users.noreply.github.com>
|
||||
Simranjeet Singh <105192966+simrnsingh@users.noreply.github.com>
|
||||
@@ -1663,6 +1716,7 @@ stevenkuang <stevenkuang@tencent.com>
|
||||
Steward Garcia <57494570+FSSRepo@users.noreply.github.com>
|
||||
StrangeBytesDev <141275258+StrangeBytesDev@users.noreply.github.com>
|
||||
strawberrymelonpanda <152940198+strawberrymelonpanda@users.noreply.github.com>
|
||||
Strongtut <Strongtut@users.noreply.github.com>
|
||||
Suaj Carrot <72162667+SuajCarrot@users.noreply.github.com>
|
||||
sudhiarm <sudhi.sathyavathy@arm.com>
|
||||
Sukriti Sharma <Ssukriti@users.noreply.github.com>
|
||||
@@ -1687,6 +1741,7 @@ Tamar <Tamar0812@outlook.co.il>
|
||||
tamarPal <tamarp3385@gmail.com>
|
||||
Tameem <113388789+AhmadTameem@users.noreply.github.com>
|
||||
Tamotsu Takahashi <ttakah+github@gmail.com>
|
||||
Tanner Bruhn <66120666+tannerbruhn@users.noreply.github.com>
|
||||
tarcey <cey.tarik@gmail.com>
|
||||
Tarek Dakhran <t.dakhran@gmail.com>
|
||||
Tarek Dakhran <tarek@liquid.ai>
|
||||
@@ -1696,6 +1751,7 @@ Taylor <quantumtraveling@gmail.com>
|
||||
tc-mb <157115220+tc-mb@users.noreply.github.com>
|
||||
TecJesh <qdvm5gl@163.com>
|
||||
Tei Home <taiteitonghome@proton.me>
|
||||
Tekin Ertekin <tekin.ertekin@gmail.com>
|
||||
Tekin Ertekin <tekinertekin@gmail.com>
|
||||
tempstudio <49735574+tempstudio@users.noreply.github.com>
|
||||
teo <TeoZosa@users.noreply.github.com>
|
||||
@@ -1737,6 +1793,7 @@ Ting Lou <louting@189.cn>
|
||||
Ting Lou <ting.lou@gmail.com>
|
||||
Ting Sun <suntcrick@gmail.com>
|
||||
Titaniumtown <titaniumtown@proton.me>
|
||||
Tiwei Bie <tiwei.btw@antgroup.com>
|
||||
tjohnman <tjohnman@users.noreply.github.com>
|
||||
Tobias Lütke <tobi@shopify.com>
|
||||
Toby <25832191+aetherbird@users.noreply.github.com>
|
||||
@@ -1813,6 +1870,7 @@ Vishal Agarwal <vishalagarwal.jss@gmail.com>
|
||||
Vishal Singh <vishal@zettabolt.com>
|
||||
Vitali Lovich <vlovich+github@gmail.com>
|
||||
Vivian <vynride@gmail.com>
|
||||
vk <89937361+itsvedantkumar@users.noreply.github.com>
|
||||
Vlad <spitfireage@gmail.com>
|
||||
Vladimir <bogdad@gmail.com>
|
||||
Vladimir Malyutin <first-leon@yandex.ru>
|
||||
@@ -1897,6 +1955,7 @@ Yaiko <elyaiko@hotmail.com>
|
||||
Yakine Tahtah <96926916+ReinforcedKnowledge@users.noreply.github.com>
|
||||
YangLe <smilingpoplar@gmail.com>
|
||||
yangli2 <yangli2@gmail.com>
|
||||
Yaniss Amazouz <yaniss91600@gmail.com>
|
||||
Yann Follet <131855179+YannFollet@users.noreply.github.com>
|
||||
Yanzhao Wang <yanzhaow@qti.qualcomm.com>
|
||||
Yarden Tal <yardent@qti.qualcomm.com>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ include(CheckIncludeFileCXX)
|
||||
|
||||
### llama.cpp version
|
||||
set(LLAMA_VERSION_MAJOR 0)
|
||||
set(LLAMA_VERSION_MINOR 3)
|
||||
set(LLAMA_VERSION_MINOR 4)
|
||||
set(LLAMA_VERSION_PATCH 0)
|
||||
set(LLAMA_VERSION_BASE "${LLAMA_VERSION_MAJOR}.${LLAMA_VERSION_MINOR}.${LLAMA_VERSION_PATCH}")
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
[](https://github.com/ggml-org/llama.cpp/actions/workflows/docker.yml)
|
||||
[](https://github.com/ggml-org/llama.cpp/actions/workflows/winget.yml)
|
||||
|
||||
[ggml](https://github.com/ggml-org/ggml) / [ops](https://github.com/ggml-org/llama.cpp/blob/master/docs/ops.md) / [maintainer PRs](https://github.com/ggml-org/llama.cpp/issues?q=is%3Apr%20is%3Aopen%20draft%3AFalse%20(author%3Argerganov%20OR%20author%3AKitaitiMakoto%20OR%20author%3Adanbev%20OR%20author%3Aaldehir%20OR%20author%3Amax-krasnyansky%20OR%20author%3ACISC%20OR%20author%3Aggerganov%20OR%20author%3Aam17an%20OR%20author%3Abartowski1182%20OR%20author%3Anikwen%20OR%20author%3Ahipudding%20OR%20author%3AServeurpersoCom%20OR%20author%3Apwilkin%20OR%20author%3Areeselevine%20OR%20author%3Angxson%20OR%20author%3Ajeffbolznv%20OR%20author%3Amarty1885%20OR%20author%3A0cc4m%20OR%20author%3ATitaniumtown%20OR%20author%3Aangt%20OR%20author%3AIMbackK%20OR%20author%3Aarthw%20OR%20author%3AJohannesGaessler%20OR%20author%3AORippler%20OR%20author%3Aruixiang63%20OR%20author%3Axctan%20OR%20author%3Aallozaur%20OR%20author%3Ayomaytk%20OR%20author%3Aaendk%20OR%20author%3Agaugarg-nv%20OR%20author%3Ataronaeo%20OR%20author%3Aforforever73%20OR%20author%3Alhez%20OR%20author%3Anetrunnereve%20OR%20author%3Afairydreaming)%20sort%3Aupdated-desc) / [dev stats](https://github.com/ggml-org/llama.cpp-dev) / [lib llama API](https://github.com/ggml-org/llama.cpp/issues/9289) / [llama-server REST API](https://github.com/ggml-org/llama.cpp/issues/9291)
|
||||
[ggml](https://github.com/ggml-org/ggml) / [ops](https://github.com/ggml-org/llama.cpp/blob/master/docs/ops.md) / [maintainer PRs](https://github.com/ggml-org/llama.cpp/issues?q=is%3Apr%20is%3Aopen%20draft%3AFalse%20(author%3Argerganov%20OR%20author%3AKitaitiMakoto%20OR%20author%3Adanbev%20OR%20author%3Aaldehir%20OR%20author%3Amax-krasnyansky%20OR%20author%3ACISC%20OR%20author%3Aggerganov%20OR%20author%3Aam17an%20OR%20author%3Ajhen0409%20OR%20author%3Abartowski1182%20OR%20author%3Anikwen%20OR%20author%3Ahipudding%20OR%20author%3Aravi9%20OR%20author%3AServeurpersoCom%20OR%20author%3Apwilkin%20OR%20author%3Areeselevine%20OR%20author%3Angxson%20OR%20author%3Ajeffbolznv%20OR%20author%3Amarty1885%20OR%20author%3A0cc4m%20OR%20author%3ATitaniumtown%20OR%20author%3Aangt%20OR%20author%3AIMbackK%20OR%20author%3Aarthw%20OR%20author%3AJohannesGaessler%20OR%20author%3AORippler%20OR%20author%3Aruixiang63%20OR%20author%3Axctan%20OR%20author%3Aallozaur%20OR%20author%3Ayomaytk%20OR%20author%3Aaendk%20OR%20author%3Awine99%20OR%20author%3Agaugarg-nv%20OR%20author%3Ataronaeo%20OR%20author%3Aforforever73%20OR%20author%3Alhez%20OR%20author%3Anetrunnereve%20OR%20author%3Afairydreaming)%20sort%3Aupdated-desc) / [dev stats](https://github.com/ggml-org/llama.cpp-dev) / [lib llama API](https://github.com/ggml-org/llama.cpp/issues/9289) / [llama-server REST API](https://github.com/ggml-org/llama.cpp/issues/9291)
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ static const command cmds[] = {
|
||||
#undef UPDATE_HIDDEN
|
||||
|
||||
static int version(int /*argc*/, char ** /*argv*/) {
|
||||
llama_print_build_info(llama_version());
|
||||
llama_print_build_info(llama_version(), stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,8 +189,8 @@ if [ ! -z ${GG_BUILD_OPENVINO} ]; then
|
||||
fi
|
||||
CMAKE_EXTRA="${CMAKE_EXTRA} -DGGML_OPENVINO=ON"
|
||||
|
||||
# TODO: fix and re-enable the `test-llama-archs` and `test-recurrent-state-rollback*`
|
||||
CTEST_EXTRA="-E test-llama-archs|^test-recurrent-state-rollback"
|
||||
# TODO: fix failing tests on OpenVINO backend
|
||||
CTEST_EXTRA="-E test-llama-archs|^test-recurrent-state-|test-backend-ops|test-save-load-state"
|
||||
fi
|
||||
|
||||
## helpers
|
||||
|
||||
@@ -29,7 +29,7 @@ const char * llama_build_info(void) {
|
||||
return s.c_str();
|
||||
}
|
||||
|
||||
void llama_print_build_info(const char * llama_version) {
|
||||
fprintf(stderr, "version: %s (build %d, commit %s)\n", llama_version, llama_build_number(), llama_commit());
|
||||
fprintf(stderr, "built with %s for %s\n", llama_compiler(), llama_build_target());
|
||||
void llama_print_build_info(const char * llama_version, FILE * stream) {
|
||||
fprintf(stream, "version: %s (build %d, commit %s)\n", llama_version, llama_build_number(), llama_commit());
|
||||
fprintf(stream, "built with %s for %s\n", llama_compiler(), llama_build_target());
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
int llama_build_number(void);
|
||||
|
||||
const char * llama_commit(void);
|
||||
@@ -8,4 +10,4 @@ const char * llama_compiler(void);
|
||||
const char * llama_build_target(void);
|
||||
const char * llama_build_info(void);
|
||||
|
||||
void llama_print_build_info(const char *);
|
||||
void llama_print_build_info(const char *, FILE * = stderr);
|
||||
|
||||
@@ -124,6 +124,7 @@ TEXT_MODEL_MAP: dict[str, str] = {
|
||||
"HunYuanMoEV1ForCausalLM": "hunyuan",
|
||||
"HunYuanVLForConditionalGeneration": "hunyuan",
|
||||
"HYV3ForCausalLM": "hunyuan",
|
||||
"HYV4ForCausalLM": "hy_v4",
|
||||
"IQuestCoderForCausalLM": "llama",
|
||||
"InternLM2ForCausalLM": "internlm",
|
||||
"InternLM3ForCausalLM": "internlm",
|
||||
|
||||
@@ -1507,6 +1507,9 @@ class TextModel(ModelBase):
|
||||
if chkhsh == "bba3b3366b646dbdded5dbc42d59598b849371afc42f7beafa914afaa5b70aa6":
|
||||
# ref: https://huggingface.co/tencent/Hunyuan-4B-Instruct
|
||||
res = "hunyuan-dense"
|
||||
if chkhsh == "e6ddf9c6686791c12d698d34c31ab9be1fea9af5a3d9a6909783ab382198ae1c":
|
||||
# ref: https://huggingface.co/tencent/Hy4-preview
|
||||
res = "hy_v4"
|
||||
if chkhsh == "a6b57017d60e6edb4d88ecc2845188e0eb333a70357e45dcc9b53964a73bbae6":
|
||||
# ref: https://huggingface.co/tiiuae/Falcon-H1-0.5B-Base
|
||||
res = "falcon-h1"
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Iterable
|
||||
|
||||
import torch
|
||||
|
||||
from .base import ModelBase, gguf, logger
|
||||
from .deepseek import DeepseekV2Model
|
||||
|
||||
|
||||
def split_kv_b_proj(weight: torch.Tensor, n_head: int, qk_nope: int, v_head_dim: int):
|
||||
"""Split kv_b_proj into k_b (transposed) and v_b, matching DeepSeek MLA absorption.
|
||||
|
||||
weight: [n_head*(qk_nope+v_head_dim), kv_lora_rank].
|
||||
Returns (k_b, v_b): k_b [n_head, kv_lora_rank, qk_nope], v_b [n_head, v_head_dim, kv_lora_rank].
|
||||
"""
|
||||
kv_lora = weight.shape[-1]
|
||||
assert weight.shape[0] == n_head * (qk_nope + v_head_dim)
|
||||
kv_b = weight.view(n_head, qk_nope + v_head_dim, kv_lora)
|
||||
k_b, v_b = torch.split(kv_b, [qk_nope, v_head_dim], dim=1)
|
||||
k_b = k_b.transpose(1, 2).contiguous() # [n_head, kv_lora, qk_nope]
|
||||
return k_b, v_b.contiguous()
|
||||
|
||||
|
||||
def split_gate_up(weight: torch.Tensor, moe_intermediate_size: int):
|
||||
"""Split a fused stacked gate_up expert tensor into (gate, up).
|
||||
|
||||
weight: [n_expert, 2*moe_intermediate_size, hidden] (gate first, up second).
|
||||
Returns (gate, up) each [n_expert, moe_intermediate_size, hidden].
|
||||
"""
|
||||
assert weight.shape[1] == 2 * moe_intermediate_size, f"{weight.shape[1]} != 2*{moe_intermediate_size}"
|
||||
gate = weight[:, :moe_intermediate_size, :].contiguous()
|
||||
up = weight[:, moe_intermediate_size:, :].contiguous()
|
||||
return gate, up
|
||||
|
||||
|
||||
@ModelBase.register("HYV4ForCausalLM")
|
||||
class HYV4Model(DeepseekV2Model):
|
||||
"""HY_V4: DeepSeek-V3 style MLA + MoE with iHC, a gated MLA output and a learnable sink.
|
||||
|
||||
Reuses DeepseekV2Model for the vocab and the MLA metadata, but overrides the tensor mapping
|
||||
because HY_V4 ships pre-stacked / fused experts plus extra iHC, gate and sink tensors. The
|
||||
rope rows are mapped straight through (no permute) - the graph rotates consecutive pairs.
|
||||
|
||||
DSA is supported: indexer weights are exported for the layers marked "full" in indexer_types.
|
||||
"shared" layers reuse the top-k of the last preceding full layer at inference time, so they
|
||||
carry no indexer weights.
|
||||
|
||||
MTP (num_nextn_predict_layers) is dropped, so the GGUF cannot be used for speculative
|
||||
decoding. The reference only runs the MTP layers while training or while speculating, so they
|
||||
cannot change single-token logits.
|
||||
"""
|
||||
|
||||
model_arch = gguf.MODEL_ARCH.HY_V4
|
||||
|
||||
# tensors a "full" indexer layer must carry
|
||||
INDEXER_SUFFIXES = frozenset({
|
||||
"self_attn.indexer.wq_b.weight",
|
||||
"self_attn.indexer.wk.weight",
|
||||
"self_attn.indexer.k_norm.weight",
|
||||
"self_attn.indexer.k_norm.bias",
|
||||
"self_attn.indexer.weights_proj.weight",
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def filter_tensors(cls, item):
|
||||
# drop MTP here, not in modify_tensors, so the weights are never read
|
||||
if item[0].startswith("model.mtp_layers."):
|
||||
return None
|
||||
return super().filter_tensors(item)
|
||||
|
||||
def _check_indexer_hparams(self):
|
||||
for key in ("index_n_heads", "index_head_dim", "index_topk"):
|
||||
if key not in self.hparams:
|
||||
raise ValueError(f"HY_V4 has DSA layers but no {key}")
|
||||
|
||||
def indexer_is_full(self) -> list[bool] | None:
|
||||
"""Per-layer indexer ownership, or None when the checkpoint has no DSA.
|
||||
|
||||
indexer_types entries are "full" (owns an indexer) or "shared" (reuses the preceding
|
||||
full layer's top-k). Missing indexer_types with sparse layers means every sparse layer
|
||||
owns one.
|
||||
"""
|
||||
hparams = self.hparams
|
||||
n_layer = hparams["num_hidden_layers"]
|
||||
indexer_types = hparams.get("indexer_types")
|
||||
|
||||
# the reference drives DSA off indexer_types alone; layer_types is only a fallback for
|
||||
# checkpoints predating it (it was renamed to deepseek_sparse_attention upstream)
|
||||
if indexer_types is None:
|
||||
layer_types = hparams.get("layer_types") or []
|
||||
sparse = {"sparse_attention", "deepseek_sparse_attention"}
|
||||
if not any(t in sparse for t in layer_types):
|
||||
return None
|
||||
if len(layer_types) < n_layer:
|
||||
raise ValueError(f"HY_V4 layer_types has {len(layer_types)} entries, need {n_layer}")
|
||||
self._check_indexer_hparams()
|
||||
return [t in sparse for t in layer_types[:n_layer]]
|
||||
|
||||
self._check_indexer_hparams()
|
||||
|
||||
if len(indexer_types) < n_layer:
|
||||
raise ValueError(f"HY_V4 indexer_types has {len(indexer_types)} entries, need {n_layer}")
|
||||
unknown = {t for t in indexer_types[:n_layer]} - {"full", "shared"}
|
||||
if unknown:
|
||||
raise ValueError(f"HY_V4 unknown indexer_types values: {sorted(unknown)}")
|
||||
is_full = [t == "full" for t in indexer_types[:n_layer]]
|
||||
if is_full and not is_full[0]:
|
||||
raise ValueError("HY_V4 layer 0 must be indexer_types 'full' (nothing precedes it to share)")
|
||||
return is_full
|
||||
|
||||
def set_gguf_parameters(self):
|
||||
hparams = self.hparams
|
||||
|
||||
# HY4 has n_group == topk_group == 1 (no group routing). Drop the keys so the base does
|
||||
# not emit expert_group_count/used; llama.cpp then takes the ungrouped MoE path.
|
||||
if hparams.get("n_group") == 1 and hparams.get("topk_group") == 1:
|
||||
hparams.pop("n_group", None)
|
||||
hparams.pop("topk_group", None)
|
||||
|
||||
# HY_V4 config expresses dense/sparse layers via mlp_layer_types, but DeepseekV2Model
|
||||
# needs first_k_dense_replace. Derive it as the contiguous leading "dense" block
|
||||
# (the real config.json also carries first_k_dense_replace; prefer it when present,
|
||||
# but assert the two agree so a mismatch fails loudly).
|
||||
mlp_types = hparams.get("mlp_layer_types")
|
||||
explicit = hparams.get("first_k_dense_replace")
|
||||
derived = None
|
||||
if mlp_types is not None:
|
||||
lead = 0
|
||||
for t in mlp_types:
|
||||
if t == "dense":
|
||||
lead += 1
|
||||
else:
|
||||
break
|
||||
if any(t == "dense" for t in mlp_types[lead:]):
|
||||
raise NotImplementedError("HY_V4 converter expects a contiguous leading dense block")
|
||||
derived = lead
|
||||
if explicit is not None and derived is not None and explicit != derived:
|
||||
raise ValueError(
|
||||
f"HY_V4 first_k_dense_replace ({explicit}) disagrees with mlp_layer_types "
|
||||
f"leading-dense count ({derived})"
|
||||
)
|
||||
if explicit is None:
|
||||
if derived is None:
|
||||
raise ValueError("HY_V4 needs first_k_dense_replace or mlp_layer_types to place dense layers")
|
||||
hparams["first_k_dense_replace"] = derived
|
||||
|
||||
# reuse DeepseekV2 MLA + MoE metadata (forces num_key_value_heads=1, writes q/kv lora,
|
||||
# key/value lengths, expert counts, weights scale/norm, rope dims, etc.)
|
||||
super().set_gguf_parameters()
|
||||
|
||||
# HY4 uses DeepSeek-V3 sigmoid routing with e_score_correction_bias. The config has no
|
||||
# scoring_func key, so the base does not write a gating func; set it explicitly.
|
||||
self.gguf_writer.add_expert_gating_func(gguf.ExpertGatingFuncType.SIGMOID)
|
||||
|
||||
# routed-expert SwiGLU logits clamp (only routed experts; shared/dense are not clamped,
|
||||
# so swiglu_clamp_shexp is intentionally not written). 0.0 disables the clamp.
|
||||
swiglu_limit = float(hparams.get("swiglu_limit", 0.0) or 0.0)
|
||||
if swiglu_limit > 0.0:
|
||||
self.gguf_writer.add_swiglu_clamp_exp([swiglu_limit] * self.block_count)
|
||||
|
||||
# iHC (independent Hyper-Connections)
|
||||
self.gguf_writer.add_hyper_connection_count(hparams["hc_mult"])
|
||||
self.gguf_writer.add_hyper_connection_epsilon(hparams["hc_eps"])
|
||||
self.gguf_writer.add_hyper_connection_magnitude(hparams["hc_magnitude"])
|
||||
|
||||
# is_full is written explicitly; the graph must not infer it from tensor presence
|
||||
is_full = self.indexer_is_full()
|
||||
if is_full is not None:
|
||||
self.gguf_writer.add_indexer_head_count(hparams["index_n_heads"])
|
||||
self.gguf_writer.add_indexer_key_length(hparams["index_head_dim"])
|
||||
self.gguf_writer.add_indexer_top_k(hparams["index_topk"])
|
||||
self.gguf_writer.add_indexer_types(is_full)
|
||||
logger.info(
|
||||
"HY_V4 DSA: %d/%d layers own an indexer (top_k=%d, n_heads=%d, head_dim=%d)",
|
||||
sum(is_full), len(is_full), hparams["index_topk"],
|
||||
hparams["index_n_heads"], hparams["index_head_dim"],
|
||||
)
|
||||
|
||||
if hparams.get("num_nextn_predict_layers", 0):
|
||||
logger.warning(
|
||||
"HY_V4: dropping %d MTP (nextn) layer(s) - the reference runs them only under "
|
||||
"training / speculative decoding. This GGUF cannot be used for speculative decoding.",
|
||||
hparams["num_nextn_predict_layers"],
|
||||
)
|
||||
|
||||
def prepare_tensors(self):
|
||||
# validate before the base materializes tensors, so a mismatch fails early
|
||||
is_full = self.indexer_is_full()
|
||||
if is_full is not None:
|
||||
present: dict[int, set[str]] = {}
|
||||
for name in self.model_tensors:
|
||||
m = re.match(r"model\.layers\.(\d+)\.(self_attn\.indexer\..+)$", name)
|
||||
if m:
|
||||
present.setdefault(int(m.group(1)), set()).add(m.group(2))
|
||||
for il, expect_full in enumerate(is_full):
|
||||
seen = present.get(il, set())
|
||||
if expect_full and seen != self.INDEXER_SUFFIXES:
|
||||
raise ValueError(
|
||||
f"HY_V4 layer {il} is indexer_types 'full' but is missing indexer tensors: "
|
||||
f"{sorted(self.INDEXER_SUFFIXES - seen)}"
|
||||
)
|
||||
if not expect_full and seen:
|
||||
raise ValueError(
|
||||
f"HY_V4 layer {il} is indexer_types 'shared' but carries indexer tensors: "
|
||||
f"{sorted(seen)}"
|
||||
)
|
||||
|
||||
super().prepare_tensors()
|
||||
|
||||
def tensor_force_quant(self, name, new_name, bid, n_dims):
|
||||
# iHC mixing matrices are 2D .weight tensors that the reference keeps in fp32
|
||||
# (_keep_in_fp32_modules_strict). 1D tensors (hc_base/scale, attn_sinks,
|
||||
# e_score_correction_bias) and the router (FFN_GATE_INP) are already forced F32 by the
|
||||
# base rules. Force the HC *_fn matrices here.
|
||||
if new_name.endswith(("hc_attn_fn.weight", "hc_ffn_fn.weight", "output_hc_fn.weight")):
|
||||
return gguf.GGMLQuantizationType.F32
|
||||
# indexer k_norm is fp32 in the reference; the base rules already cover
|
||||
# *_norm.weight and INDEXER_PROJ, but not this bias
|
||||
if self.match_model_tensor_name(new_name, gguf.MODEL_TENSOR.INDEXER_K_NORM, bid, suffix=".bias"):
|
||||
return gguf.GGMLQuantizationType.F32
|
||||
# enable_lm_head_fp32: mirror the reference fp32 LM-head matmul by keeping output F32.
|
||||
if new_name == "output.weight" and self.hparams.get("enable_lm_head_fp32", False):
|
||||
return gguf.GGMLQuantizationType.F32
|
||||
return super().tensor_force_quant(name, new_name, bid, n_dims)
|
||||
|
||||
def modify_tensors(self, data_torch: torch.Tensor, name: str, bid: int | None) -> Iterable[tuple[str, torch.Tensor]]:
|
||||
hparams = self.hparams
|
||||
n_head = hparams["num_attention_heads"]
|
||||
qk_nope = hparams["qk_nope_head_dim"]
|
||||
v_head_dim = hparams["v_head_dim"]
|
||||
moe_inter = hparams["moe_intermediate_size"]
|
||||
|
||||
tn = self.format_tensor_name
|
||||
|
||||
# ---- global (non per-layer) ----
|
||||
if name == "model.embed_tokens.weight":
|
||||
return [(tn(gguf.MODEL_TENSOR.TOKEN_EMBD), data_torch)]
|
||||
if name == "model.norm.weight":
|
||||
return [(tn(gguf.MODEL_TENSOR.OUTPUT_NORM), data_torch)]
|
||||
if name == "lm_head.weight":
|
||||
return [(tn(gguf.MODEL_TENSOR.OUTPUT), data_torch)]
|
||||
if name == "model.hc_head.hc_head_fn":
|
||||
return [(tn(gguf.MODEL_TENSOR.HC_HEAD_FN), data_torch)]
|
||||
if name == "model.hc_head.hc_head_base":
|
||||
return [(tn(gguf.MODEL_TENSOR.HC_HEAD_BASE), data_torch)]
|
||||
if name == "model.hc_head.hc_head_scale":
|
||||
return [(tn(gguf.MODEL_TENSOR.HC_HEAD_SCALE), data_torch)]
|
||||
|
||||
assert bid is not None, f"expected a per-layer tensor, got {name!r}"
|
||||
|
||||
# ---- per-layer, keyed by suffix after 'model.layers.{bid}.' ----
|
||||
suffix = name.split(f"model.layers.{bid}.", 1)[-1]
|
||||
|
||||
# note: q_b_proj and kv_a_proj_with_mqa are mapped straight through (no RoPE permute),
|
||||
# the graph rotates consecutive pairs so the rows need no reordering
|
||||
simple = {
|
||||
"input_layernorm.weight": (gguf.MODEL_TENSOR.ATTN_NORM, ".weight"),
|
||||
"post_attention_layernorm.weight": (gguf.MODEL_TENSOR.FFN_NORM, ".weight"),
|
||||
"self_attn.q_a_proj.weight": (gguf.MODEL_TENSOR.ATTN_Q_A, ".weight"),
|
||||
"self_attn.q_a_layernorm.weight": (gguf.MODEL_TENSOR.ATTN_Q_A_NORM, ".weight"),
|
||||
"self_attn.q_b_proj.weight": (gguf.MODEL_TENSOR.ATTN_Q_B, ".weight"),
|
||||
"self_attn.kv_a_proj_with_mqa.weight": (gguf.MODEL_TENSOR.ATTN_KV_A_MQA, ".weight"),
|
||||
"self_attn.kv_a_layernorm.weight": (gguf.MODEL_TENSOR.ATTN_KV_A_NORM, ".weight"),
|
||||
"self_attn.o_proj.weight": (gguf.MODEL_TENSOR.ATTN_OUT, ".weight"),
|
||||
"self_attn.linear_gate.weight": (gguf.MODEL_TENSOR.ATTN_GATE, ".weight"),
|
||||
"self_attn.learnable_sink_param": (gguf.MODEL_TENSOR.ATTN_SINKS, ".weight"),
|
||||
"self_attn.indexer.wq_b.weight": (gguf.MODEL_TENSOR.INDEXER_ATTN_Q_B, ".weight"),
|
||||
"self_attn.indexer.wk.weight": (gguf.MODEL_TENSOR.INDEXER_ATTN_K, ".weight"),
|
||||
"self_attn.indexer.k_norm.weight": (gguf.MODEL_TENSOR.INDEXER_K_NORM, ".weight"),
|
||||
"self_attn.indexer.k_norm.bias": (gguf.MODEL_TENSOR.INDEXER_K_NORM, ".bias"),
|
||||
"self_attn.indexer.weights_proj.weight": (gguf.MODEL_TENSOR.INDEXER_PROJ, ".weight"),
|
||||
"hc_attn_layer.hc_pre.hc_fn": (gguf.MODEL_TENSOR.HC_ATTN_FN, ".weight"),
|
||||
"hc_attn_layer.hc_pre.hc_base": (gguf.MODEL_TENSOR.HC_ATTN_BASE, ".weight"),
|
||||
"hc_attn_layer.hc_pre.hc_scale": (gguf.MODEL_TENSOR.HC_ATTN_SCALE, ".weight"),
|
||||
"hc_mlp_layer.hc_pre.hc_fn": (gguf.MODEL_TENSOR.HC_FFN_FN, ".weight"),
|
||||
"hc_mlp_layer.hc_pre.hc_base": (gguf.MODEL_TENSOR.HC_FFN_BASE, ".weight"),
|
||||
"hc_mlp_layer.hc_pre.hc_scale": (gguf.MODEL_TENSOR.HC_FFN_SCALE, ".weight"),
|
||||
"mlp.gate.weight": (gguf.MODEL_TENSOR.FFN_GATE_INP, ".weight"),
|
||||
"mlp.gate.e_score_correction.bias":(gguf.MODEL_TENSOR.FFN_EXP_PROBS_B, ".bias"),
|
||||
"mlp.gate_proj.weight": (gguf.MODEL_TENSOR.FFN_GATE, ".weight"),
|
||||
"mlp.up_proj.weight": (gguf.MODEL_TENSOR.FFN_UP, ".weight"),
|
||||
"mlp.down_proj.weight": (gguf.MODEL_TENSOR.FFN_DOWN, ".weight"),
|
||||
"mlp.shared_experts.gate_proj.weight": (gguf.MODEL_TENSOR.FFN_GATE_SHEXP, ".weight"),
|
||||
"mlp.shared_experts.up_proj.weight": (gguf.MODEL_TENSOR.FFN_UP_SHEXP, ".weight"),
|
||||
"mlp.shared_experts.down_proj.weight": (gguf.MODEL_TENSOR.FFN_DOWN_SHEXP, ".weight"),
|
||||
}
|
||||
if suffix in simple:
|
||||
key, sfx = simple[suffix]
|
||||
return [(tn(key, bid, sfx), data_torch)]
|
||||
|
||||
# kv_b_proj: split into k_b (transposed) and v_b
|
||||
if suffix == "self_attn.kv_b_proj.weight":
|
||||
k_b, v_b = split_kv_b_proj(data_torch, n_head, qk_nope, v_head_dim)
|
||||
return [
|
||||
(tn(gguf.MODEL_TENSOR.ATTN_K_B, bid), k_b),
|
||||
(tn(gguf.MODEL_TENSOR.ATTN_V_B, bid), v_b),
|
||||
]
|
||||
|
||||
# fused stacked experts: split gate_up into gate/up
|
||||
if suffix == "mlp.experts.gate_up_proj":
|
||||
gate, up = split_gate_up(data_torch, moe_inter)
|
||||
return [
|
||||
(tn(gguf.MODEL_TENSOR.FFN_GATE_EXP, bid), gate),
|
||||
(tn(gguf.MODEL_TENSOR.FFN_UP_EXP, bid), up),
|
||||
]
|
||||
if suffix == "mlp.experts.down_proj":
|
||||
return [(tn(gguf.MODEL_TENSOR.FFN_DOWN_EXP, bid), data_torch)]
|
||||
|
||||
raise ValueError(f"Unsupported HY_V4 tensor {name!r} (suffix {suffix!r})")
|
||||
@@ -176,6 +176,7 @@ pre_computed_hashes = [
|
||||
{"name": "minerva-7b", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/sapienzanlp/Minerva-7B-base-v1.0", "chkhsh": "1431a23e583c97432bc230bff598d103ddb5a1f89960c8f1d1051aaa944d0b35"},
|
||||
{"name": "hunyuan", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/tencent/Hunyuan-A13B-Instruct", "chkhsh": "7e57df22b1fe23a7b1e1c7f3dc4e3f96d43a4eb0836d0c6bdc3436d7b2f1c664"},
|
||||
{"name": "hunyuan-dense", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/tencent/Hunyuan-4B-Instruct", "chkhsh": "bba3b3366b646dbdded5dbc42d59598b849371afc42f7beafa914afaa5b70aa6"},
|
||||
{"name": "hy_v4", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/tencent/Hy4-preview", "chkhsh": "e6ddf9c6686791c12d698d34c31ab9be1fea9af5a3d9a6909783ab382198ae1c"},
|
||||
# falcon-h1 series uses 4 different tokenizers across model sizes (0.5b - 34b), hence we need to define 4 different hashes
|
||||
{"name": "falcon-h1", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/tiiuae/Falcon-H1-0.5B-Base", "chkhsh": "a6b57017d60e6edb4d88ecc2845188e0eb333a70357e45dcc9b53964a73bbae6"},
|
||||
{"name": "falcon-h1", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/tiiuae/Falcon-H1-1B-Base", "chkhsh": "60476e1243776c4fb1b993dbd7a5f15ac22f83c80afdf425fa5ae01c8d44ef86"},
|
||||
|
||||
@@ -805,6 +805,8 @@ User can use the device management in [docs/multi-gpu.md](https://github.com/ggm
|
||||
| GGML_SYCL_ENABLE_VMM | 0 or 1 (default) | Enable the virtual-memory device pool. |
|
||||
| GGML_SYCL_ENABLE_MKL_FA | 1 (default) or 0 | Enable oneMKL GEMM flash attention for XMX-accelerated prompt processing with quantized KV cache. Automatically activates during prefill (prompt processing) when all conditions are met: (1) flash-attn enabled (`-fa` or `--flash-attn on`), (2) KV cache quantized (`--cache-type-k q8_0 --cache-type-v q8_0` or other `*_0/*_1` types), (3) batch size ≥ 1024 (`--batch-size 1024`), (4) prompt length ≥ 1024 tokens. Set to 0 to force the TILE kernel for A/B testing. Example minimum command: `llama-cli -m model.gguf -fa -ngl 99 --cache-type-k q8_0 --cache-type-v q8_0 --batch-size 1024 -p "your prompt"` |
|
||||
| GGML_SYCL_MKL_FA_DEBUG | 0 (default) or 1 | Enable per-call diagnostic logging for MKL flash attention: GEMM/softmax timings, interleaved-head detection, and buffer memory usage. |
|
||||
| GGML_SYCL_MEMTRACE | 0 (default), 1, 2 | Enable record and output memory allocation diagnostics. Requires `-lv 4`. <br>0 - Disable<br>1 - Basic memory info, including current and peak allocations, as well allocations from other sources, around 50 lines per model load.<br>2 - More verbose, logging around 900 specific allocations and deallocations. |
|
||||
| GGML_SYCL_MEMTRACE_STEP | 64 (default) or positive integer | With GGML_SYCL_MEMTRACE=1, the minimum growth in memory usage to trigger another log record. |
|
||||
| GGML_SYCL_MKL_FA_DIAG | 0 (default) or 1 | Enable output fingerprinting for MKL flash attention. Dumps the first 64 float output values for the first 6 FA calls with n_kv ≥ 1024, labeled with kernel type (MKL/TILE/VEC) for cross-kernel comparison. |
|
||||
| GGML_SYCL_ENABLE_FUSION | 0 or 1 (default) | Enable fused-kernel dispatch in graph compute. Unsupported types and layouts fall back to the standalone op kernels. See `ggml_sycl_can_fuse()`. |
|
||||
| GGML_SYCL_ENABLE_ESIMD | 0 or 1 (default)| Enable ESIMD kernels when available. |
|
||||
|
||||
@@ -300,7 +300,6 @@ The following compilation options are also available to tweak performance:
|
||||
|-------------------------------|------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| GGML_CUDA_FORCE_MMQ | Boolean | false | Force the use of custom matrix multiplication kernels for quantized models instead of FP16 cuBLAS even if there is no int8 tensor core implementation available (affects V100, CDNA and RDNA3+). MMQ kernels are enabled by default on GPUs with int8 tensor core support. With MMQ force enabled, speed for large batch sizes will be worse but VRAM consumption will be lower. |
|
||||
| GGML_CUDA_FORCE_CUBLAS | Boolean | false | Force the use of FP16 cuBLAS instead of custom matrix multiplication kernels for quantized models. There may be issues with numerical overflows (except for V100, CDNA and RDNA4 which use FP32 compute type by default) and memory use will be higher. Prompt processing may become faster on recent datacenter GPUs (the custom kernels were tuned primarily for RTX 3000/4000). |
|
||||
| GGML_CUDA_PEER_MAX_BATCH_SIZE | Positive integer | 128 | Maximum batch size for which to enable peer access between multiple GPUs. Peer access requires either Linux or NVLink. When using NVLink enabling peer access for larger batch sizes is potentially beneficial. |
|
||||
| GGML_CUDA_FA_ALL_QUANTS | Boolean | false | Compile support for all KV cache quantization type (combinations) for the FlashAttention CUDA kernels. More fine-grained control over KV cache size but compilation takes much longer. |
|
||||
|
||||
## MUSA
|
||||
|
||||
+1
-7
@@ -4,7 +4,7 @@ project("ggml" C CXX ASM)
|
||||
|
||||
### GGML Version
|
||||
set(GGML_VERSION_MAJOR 0)
|
||||
set(GGML_VERSION_MINOR 22)
|
||||
set(GGML_VERSION_MINOR 23)
|
||||
set(GGML_VERSION_PATCH 0)
|
||||
set(GGML_VERSION_BASE "${GGML_VERSION_MAJOR}.${GGML_VERSION_MINOR}.${GGML_VERSION_PATCH}")
|
||||
|
||||
@@ -200,8 +200,6 @@ option(GGML_CUDA "ggml: use CUDA"
|
||||
option(GGML_MUSA "ggml: use MUSA" OFF)
|
||||
option(GGML_CUDA_FORCE_MMQ "ggml: use mmq kernels instead of cuBLAS" OFF)
|
||||
option(GGML_CUDA_FORCE_CUBLAS "ggml: always use cuBLAS instead of mmq kernels" OFF)
|
||||
set (GGML_CUDA_PEER_MAX_BATCH_SIZE "128" CACHE STRING
|
||||
"ggml: max. batch size for using peer access")
|
||||
option(GGML_CUDA_NO_PEER_COPY "ggml: do not use peer to peer copies" OFF)
|
||||
option(GGML_CUDA_NO_VMM "ggml: do not try to use CUDA VMM" OFF)
|
||||
option(GGML_CUDA_FA "ggml: compile ggml FlashAttention CUDA kernels" ON)
|
||||
@@ -406,10 +404,6 @@ write_basic_package_version_file(
|
||||
VERSION ${GGML_INSTALL_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
target_compile_definitions(ggml-base PRIVATE
|
||||
GGML_VERSION="${GGML_INSTALL_VERSION}"
|
||||
GGML_COMMIT="${GGML_BUILD_COMMIT}"
|
||||
)
|
||||
message(STATUS "ggml version: ${GGML_INSTALL_VERSION}")
|
||||
message(STATUS "ggml commit: ${GGML_BUILD_COMMIT}")
|
||||
|
||||
|
||||
@@ -424,10 +424,6 @@ extern "C" {
|
||||
// Compare the output of two backends
|
||||
GGML_API bool ggml_backend_compare_graph_backend(ggml_backend_t backend1, ggml_backend_t backend2, struct ggml_cgraph * graph, ggml_backend_eval_callback callback, void * user_data, struct ggml_tensor const * const * test_nodes, size_t num_test_nodes);
|
||||
|
||||
// returns true for ops that may require additional memory for fleeting data on some backends,
|
||||
// i.e. the backend's get_alloc_size may return more than ggml_nbytes for the output tensor
|
||||
GGML_API bool ggml_backend_op_alloc_size_may_expand(enum ggml_op op);
|
||||
|
||||
// Tensor initialization
|
||||
GGML_API enum ggml_status ggml_backend_tensor_alloc(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor, void * addr);
|
||||
GGML_API enum ggml_status ggml_backend_view_init(struct ggml_tensor * tensor);
|
||||
|
||||
@@ -213,7 +213,9 @@ set_target_properties(ggml-base PROPERTIES
|
||||
SOVERSION ${GGML_VERSION_MAJOR}
|
||||
)
|
||||
|
||||
target_include_directories(ggml-base PRIVATE .)
|
||||
configure_file(ggml-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/ggml-version.h @ONLY)
|
||||
|
||||
target_include_directories(ggml-base PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if (GGML_BACKEND_DL)
|
||||
target_compile_definitions(ggml-base PUBLIC GGML_BACKEND_DL)
|
||||
endif()
|
||||
|
||||
@@ -34,6 +34,11 @@ extern "C" {
|
||||
void * context;
|
||||
};
|
||||
|
||||
// [TAG_ALLOC_SIZE_EXPAND]
|
||||
// returns true for ops that may require additional memory for fleeting data on some backends,
|
||||
// i.e. the backend buffer type's get_alloc_size may return more than ggml_nbytes for the output tensor
|
||||
GGML_API bool ggml_op_alloc_size_may_expand(enum ggml_op op);
|
||||
|
||||
//
|
||||
// Backend buffer
|
||||
//
|
||||
|
||||
@@ -490,7 +490,13 @@ static ggml_backend_reg_t ggml_backend_load_best(const char * name, bool silent,
|
||||
#endif
|
||||
// default search paths: executable directory, current directory
|
||||
search_paths.push_back(get_executable_path());
|
||||
search_paths.push_back(fs::current_path());
|
||||
std::error_code cwd_ec;
|
||||
const fs::path cwd = fs::current_path(cwd_ec);
|
||||
if (cwd_ec) {
|
||||
GGML_LOG_DEBUG("%s: current_path() failure, error-message: %s\n", __func__, cwd_ec.message().c_str());
|
||||
} else {
|
||||
search_paths.push_back(cwd);
|
||||
}
|
||||
} else {
|
||||
search_paths.push_back(fs::u8path(user_search_path));
|
||||
}
|
||||
@@ -508,8 +514,14 @@ static ggml_backend_reg_t ggml_backend_load_best(const char * name, bool silent,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fs::directory_iterator dir_it(search_path, fs::directory_options::skip_permission_denied);
|
||||
for (const auto & entry : dir_it) {
|
||||
std::error_code dir_ec;
|
||||
fs::directory_iterator dir_it(search_path, fs::directory_options::skip_permission_denied, dir_ec);
|
||||
if (dir_ec) {
|
||||
GGML_LOG_DEBUG("%s: failed to enumerate %s: %s\n", __func__, path_str(search_path).c_str(), dir_ec.message().c_str());
|
||||
continue;
|
||||
}
|
||||
for (const fs::directory_iterator end; dir_it != end; dir_it.increment(dir_ec)) {
|
||||
const auto & entry = *dir_it;
|
||||
if (entry.is_regular_file(ec)) {
|
||||
auto filename = entry.path().filename();
|
||||
auto ext = entry.path().extension();
|
||||
|
||||
@@ -71,7 +71,7 @@ size_t ggml_backend_buft_get_alloc_size(ggml_backend_buffer_type_t buft, const s
|
||||
GGML_ASSERT(size <= ggml_nbytes(tensor) ||
|
||||
ggml_op_is_empty(tensor->op) ||
|
||||
ggml_is_quantized(tensor->type) || // [TAG_ALLOC_SIZE_EXPAND]
|
||||
ggml_backend_op_alloc_size_may_expand(tensor->op));
|
||||
ggml_op_alloc_size_may_expand(tensor->op));
|
||||
|
||||
return size;
|
||||
}
|
||||
@@ -2109,10 +2109,7 @@ ggml_backend_t ggml_backend_sched_get_tensor_backend(ggml_backend_sched_t sched,
|
||||
|
||||
// utils
|
||||
|
||||
// [TAG_ALLOC_SIZE_EXPAND]
|
||||
// returns true for ops that may require additional memory for fleeting data on some backends,
|
||||
// i.e. the backend's get_alloc_size may return more than ggml_nbytes for the output tensor
|
||||
bool ggml_backend_op_alloc_size_may_expand(enum ggml_op op) {
|
||||
bool ggml_op_alloc_size_may_expand(enum ggml_op op) {
|
||||
switch (op) {
|
||||
case GGML_OP_FLASH_ATTN_EXT:
|
||||
case GGML_OP_MUL_MAT:
|
||||
|
||||
@@ -636,7 +636,7 @@ void ggml_vec_dot_q5_1_q8_1(int n, float * GGML_RESTRICT s, size_t bs, const voi
|
||||
const float32x4_t v_xyf = vec_float(v_xy);
|
||||
|
||||
const float32x4_t v_d = vec_splats(GGML_CPU_FP16_TO_FP32(x0->d) * GGML_CPU_FP16_TO_FP32(y0->d));
|
||||
const float32x4_t v_acc = vec_madd(v_xyf, v_d, v_acc);
|
||||
const float32x4_t v_acc = vec_madd(v_xyf, v_d, vec_splats(0.0f));
|
||||
|
||||
sumf += vec_hsum_f32x4(v_acc) + summs;
|
||||
}
|
||||
|
||||
@@ -129,8 +129,6 @@ if (CUDAToolkit_FOUND)
|
||||
${GGML_SOURCES_CUDA}
|
||||
)
|
||||
|
||||
add_compile_definitions(GGML_CUDA_PEER_MAX_BATCH_SIZE=${GGML_CUDA_PEER_MAX_BATCH_SIZE})
|
||||
|
||||
if (GGML_CUDA_GRAPHS)
|
||||
add_compile_definitions(GGML_CUDA_USE_GRAPHS)
|
||||
endif()
|
||||
|
||||
@@ -111,6 +111,7 @@ ggml_metal_t ggml_metal_init(ggml_metal_device_t dev) {
|
||||
id<MTLCommandQueue> queue = ggml_metal_device_get_queue(dev);
|
||||
if (queue == nil) {
|
||||
GGML_LOG_ERROR("%s: error: failed to create command queue\n", __func__);
|
||||
free(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1248,6 +1248,153 @@ constexpr fa_vec_entry_t fa_vec_tuned_table[] = {
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_F16, 512, 512, 2, 0 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_F16, 512, 512, 2, 1 }, { 4, 1 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_F16, 512, 512, 2, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 32, 32, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 32, 32, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 32, 32, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 32, 32, 2, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 32, 32, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 32, 32, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 64, 64, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 64, 64, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 64, 64, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 64, 64, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 96, 96, 1, 3 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 96, 96, 2, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 96, 96, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 128, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 192, 192, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 192, 128, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 320, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 576, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_0, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 1, 3 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 2, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 32, 32, 3, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 64, 64, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 64, 64, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 64, 64, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 64, 64, 2, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 64, 64, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 96, 96, 2, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 96, 96, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 128, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 128, 128, 1, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 128, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 128, 128, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 192, 192, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 192, 192, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 192, 192, 2, 3 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 192, 128, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 320, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 576, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q4_1, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 32, 32, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 32, 32, 2, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 96, 96, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 96, 96, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 192, 1, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 192, 1, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 192, 2, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 192, 3, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, 2, 3 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 192, 128, 3, 3 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 256, 256, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 256, 256, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 256, 256, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 256, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 320, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 576, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_0, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 32, 32, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 96, 96, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 96, 96, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 128, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 128, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 192, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 192, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 192, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, -1, 1 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 192, 128, 3, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 320, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 576, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q5_1, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q8_0, 32, 32, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q8_0, 32, 32, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M2_MAX, GGML_TYPE_Q8_0, 32, 32, 2, 2 }, { 4, 4 } },
|
||||
@@ -1525,6 +1672,178 @@ constexpr fa_vec_entry_t fa_vec_tuned_table[] = {
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_F16, 576, 512, 2, 1 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_F16, 576, 512, 2, 2 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_F16, 576, 512, 3, 1 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 32, 32, 2, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 64, 64, 3, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 96, 96, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 96, 96, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 96, 96, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 128, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 128, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 128, 128, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, 3, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, 3, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 192, 3, 3 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 192, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 320, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 320, 256, 3, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 576, 512, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 576, 512, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_0, 576, 512, 1, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 32, 32, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 32, 32, 2, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 64, 64, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 96, 96, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 96, 96, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 96, 96, 1, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 96, 96, 2, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, 1, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, 3, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, 3, 2 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 128, 128, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 192, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 192, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 192, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 192, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 320, 256, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 320, 256, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 320, 256, 1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 320, 256, 2, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 320, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 320, 256, 3, 3 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 512, 512, 2, 0 }, { 4, 1 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 512, 512, 2, 4 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 512, 512, 3, 1 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 512, 512, 3, 2 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 576, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q4_1, 576, 512, 1, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 96, 96, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 96, 96, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 128, 128, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 128, 128, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 128, 128, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 128, 128, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 128, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 128, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 128, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 128, 2, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 192, 128, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 256, 256, -1, 0 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 256, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 256, 256, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 256, 256, 2, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 256, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 320, 256, 1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 320, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 320, 256, 2, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 320, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 512, 512, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 576, 512, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 576, 512, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 576, 512, 1, 1 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_0, 576, 512, 1, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 96, 96, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 96, 96, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 128, 128, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 128, 128, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 128, 128, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 128, 128, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 128, 128, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, 1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, -1, 1 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, 1, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 192, 128, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 256, 256, -1, 0 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 256, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 256, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 320, 256, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 320, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 320, 256, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 320, 256, 2, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 320, 256, 3, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 576, 512, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 576, 512, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 576, 512, 2, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 576, 512, 3, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q5_1, 576, 512, 3, 3 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q8_0, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q8_0, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3, GGML_TYPE_Q8_0, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
@@ -1826,6 +2145,151 @@ constexpr fa_vec_entry_t fa_vec_tuned_table[] = {
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_F16, 576, 512, 2, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_F16, 576, 512, 2, 3 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_F16, 576, 512, 3, 1 }, { 4, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 32, 32, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 32, 32, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 32, 32, 3, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 32, 32, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 32, 32, 3, 4 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 64, 64, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 96, 96, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 96, 96, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 96, 96, 1, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 96, 96, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 96, 96, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 128, 128, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 192, 192, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 192, 128, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 192, 128, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 192, 128, 3, 3 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 320, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, 3, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, 1, 1 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, 1, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, 1, 3 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_0, 576, 512, 1, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 32, 32, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 32, 32, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 32, 32, 3, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 32, 32, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 32, 32, 3, 4 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 64, 64, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 96, 96, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 96, 96, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 96, 96, 1, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 96, 96, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 96, 96, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, 1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, 1, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 128, 128, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 192, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 128, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 128, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 192, 128, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 256, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 320, 256, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 576, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q4_1, 576, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 32, 32, 2, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 96, 96, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 96, 96, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 96, 96, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 96, 96, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 96, 96, 3, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 192, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 256, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 256, 256, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 256, 256, 1, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 256, 256, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 256, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 320, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 320, 256, 1, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 320, 256, 2, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 320, 256, 3, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 320, 256, 3, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 576, 512, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 576, 512, 2, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 576, 512, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 576, 512, 2, 3 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_0, 576, 512, 2, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 32, 32, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 32, 32, 2, 4 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 32, 32, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 64, 64, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 64, 64, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 64, 64, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 64, 64, 2, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 64, 64, 3, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 96, 96, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 96, 96, 1, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 96, 96, 1, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 96, 96, 2, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 96, 96, 2, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 96, 96, 3, 3 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 128, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 128, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 128, 128, 2, 2 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 192, 192, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 192, 192, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 192, 128, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 192, 128, -1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 256, 256, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 256, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 256, 256, 1, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 256, 256, 1, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 256, 256, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 256, 256, 3, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 320, 256, -1, 1 }, { 2, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 320, 256, 1, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 320, 256, 2, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 320, 256, 2, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 320, 256, 3, 2 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 320, 256, 3, 4 }, { 1, 2 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 512, 512, -1, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 512, 512, -1, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 576, 512, 2, 0 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 576, 512, 2, 1 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 576, 512, 2, 2 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 576, 512, 2, 3 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q5_1, 576, 512, 2, 4 }, { 1, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q8_0, 32, 32, -1, 1 }, { 4, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q8_0, 32, 32, 1, 1 }, { 2, 4 } },
|
||||
{ { GGML_METAL_DEVICE_M3_MAX, GGML_TYPE_Q8_0, 32, 32, 1, 4 }, { 2, 4 } },
|
||||
|
||||
@@ -75,7 +75,6 @@ if (MUSAToolkit_FOUND)
|
||||
endif()
|
||||
|
||||
add_compile_definitions(GGML_USE_MUSA)
|
||||
add_compile_definitions(GGML_CUDA_PEER_MAX_BATCH_SIZE=${GGML_CUDA_PEER_MAX_BATCH_SIZE})
|
||||
|
||||
if (GGML_MUSA_GRAPHS)
|
||||
add_compile_definitions(GGML_MUSA_GRAPHS)
|
||||
|
||||
@@ -222,6 +222,7 @@ set(GGML_OPENCL_KERNELS
|
||||
exp
|
||||
expm1
|
||||
abs
|
||||
unary_ext
|
||||
softplus
|
||||
pad
|
||||
repeat
|
||||
@@ -238,7 +239,7 @@ set(GGML_OPENCL_KERNELS
|
||||
)
|
||||
|
||||
if (GGML_OPENCL_USE_ADRENO_KERNELS)
|
||||
list(APPEND GGML_OPENCL_KERNELS gemm_xmem_f16_f32_os8)
|
||||
list(APPEND GGML_OPENCL_KERNELS gemm_xmem_f16_f32_os8 sdpa_xmem_f32_f16_os8)
|
||||
endif ()
|
||||
|
||||
foreach (K ${GGML_OPENCL_KERNELS})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +1,66 @@
|
||||
kernel void kernel_concat_f32(
|
||||
global const char * src0,
|
||||
ulong offset0,
|
||||
global const char * src1,
|
||||
ulong offset1,
|
||||
global char * dst,
|
||||
ulong offsetd,
|
||||
int ne00,
|
||||
int ne01,
|
||||
int ne02,
|
||||
int ne03,
|
||||
ulong nb00,
|
||||
ulong nb01,
|
||||
ulong nb02,
|
||||
ulong nb03,
|
||||
ulong nb10,
|
||||
ulong nb11,
|
||||
ulong nb12,
|
||||
ulong nb13,
|
||||
int ne0,
|
||||
ulong nb0,
|
||||
ulong nb1,
|
||||
ulong nb2,
|
||||
ulong nb3,
|
||||
int dim
|
||||
) {
|
||||
src0 = src0 + offset0;
|
||||
src1 = src1 + offset1;
|
||||
dst = dst + offsetd;
|
||||
// concat is a pure copy, so the kernels are keyed by element byte size
|
||||
// (1/2/4/8) rather than logical type, matching the CUDA backend.
|
||||
|
||||
const int i3 = get_group_id(2);
|
||||
const int i2 = get_group_id(1);
|
||||
const int i1 = get_group_id(0);
|
||||
|
||||
int o[4] = {0, 0, 0, 0};
|
||||
o[dim] = dim == 0 ? ne00 : (dim == 1 ? ne01 : (dim == 2 ? ne02 : ne03));
|
||||
|
||||
global const float * x;
|
||||
|
||||
for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) {
|
||||
if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) {
|
||||
x = (global const float *)(src0 + (i3 )*nb03 + (i2 )*nb02 + (i1 )*nb01 + (i0 )*nb00);
|
||||
} else {
|
||||
x = (global const float *)(src1 + (i3 - o[3])*nb13 + (i2 - o[2])*nb12 + (i1 - o[1])*nb11 + (i0 - o[0])*nb10);
|
||||
}
|
||||
|
||||
global float * y = (global float *)(dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||
|
||||
*y = *x;
|
||||
}
|
||||
#define KERNEL_CONCAT(SUFFIX, T) \
|
||||
kernel void kernel_concat_##SUFFIX( \
|
||||
global const char * src0, \
|
||||
ulong offset0, \
|
||||
global const char * src1, \
|
||||
ulong offset1, \
|
||||
global char * dst, \
|
||||
ulong offsetd, \
|
||||
int ne00, \
|
||||
int ne01, \
|
||||
int ne02, \
|
||||
int ne03, \
|
||||
ulong nb00, \
|
||||
ulong nb01, \
|
||||
ulong nb02, \
|
||||
ulong nb03, \
|
||||
ulong nb10, \
|
||||
ulong nb11, \
|
||||
ulong nb12, \
|
||||
ulong nb13, \
|
||||
int ne0, \
|
||||
ulong nb0, \
|
||||
ulong nb1, \
|
||||
ulong nb2, \
|
||||
ulong nb3, \
|
||||
int dim \
|
||||
) { \
|
||||
src0 = src0 + offset0; \
|
||||
src1 = src1 + offset1; \
|
||||
dst = dst + offsetd; \
|
||||
\
|
||||
const int i3 = get_group_id(2); \
|
||||
const int i2 = get_group_id(1); \
|
||||
const int i1 = get_group_id(0); \
|
||||
\
|
||||
int o[4] = {0, 0, 0, 0}; \
|
||||
o[dim] = dim == 0 ? ne00 : (dim == 1 ? ne01 : (dim == 2 ? ne02 : ne03)); \
|
||||
\
|
||||
global const T * x; \
|
||||
\
|
||||
for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) { \
|
||||
if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) { \
|
||||
x = (global const T *)(src0 + (i3 )*nb03 + (i2 )*nb02 + (i1 )*nb01 + (i0 )*nb00); \
|
||||
} else { \
|
||||
x = (global const T *)(src1 + (i3 - o[3])*nb13 + (i2 - o[2])*nb12 + (i1 - o[1])*nb11 + (i0 - o[0])*nb10); \
|
||||
} \
|
||||
\
|
||||
global T * y = (global T *)(dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0); \
|
||||
\
|
||||
*y = *x; \
|
||||
} \
|
||||
}
|
||||
|
||||
kernel void kernel_concat_f32_pack(
|
||||
KERNEL_CONCAT(b1, char)
|
||||
KERNEL_CONCAT(b2, short)
|
||||
KERNEL_CONCAT(b4, int)
|
||||
KERNEL_CONCAT(b8, long)
|
||||
|
||||
// packed variant for the common dim==0, small-ne0 case (4-byte elements only).
|
||||
kernel void kernel_concat_b4_pack(
|
||||
global const char * src0,
|
||||
ulong offset0,
|
||||
global const char * src1,
|
||||
@@ -104,14 +114,14 @@ kernel void kernel_concat_f32_pack(
|
||||
o[dim] = dim == 0 ? ne00 : (dim == 1 ? ne01 : (dim == 2 ? ne02 : ne03));
|
||||
|
||||
for (int i0 = lane; i0 < ne0; i0 += tpr) {
|
||||
global const float * x;
|
||||
global const int * x;
|
||||
if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) {
|
||||
x = (global const float *)(src0 + (i3 )*nb03 + (i2 )*nb02 + (i1 )*nb01 + (i0 )*nb00);
|
||||
x = (global const int *)(src0 + (i3 )*nb03 + (i2 )*nb02 + (i1 )*nb01 + (i0 )*nb00);
|
||||
} else {
|
||||
x = (global const float *)(src1 + (i3 - o[3])*nb13 + (i2 - o[2])*nb12 + (i1 - o[1])*nb11 + (i0 - o[0])*nb10);
|
||||
x = (global const int *)(src1 + (i3 - o[3])*nb13 + (i2 - o[2])*nb12 + (i1 - o[1])*nb11 + (i0 - o[0])*nb10);
|
||||
}
|
||||
|
||||
global float * y = (global float *)(dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||
global int * y = (global int *)(dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||
|
||||
*y = *x;
|
||||
}
|
||||
|
||||
@@ -286,3 +286,28 @@ kernel void kernel_cpy_i32_i32(
|
||||
dst_data[i00] = src[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Contiguous f32 copy, one work item per float4 over the whole tensor. The kernels above map
|
||||
// one workgroup to each row, which leaves a tensor with few long rows on a single compute unit.
|
||||
// vload4/vstore4 rather than a float4 cast: these buffers carry an arbitrary 4-byte view offset.
|
||||
kernel void kernel_cpy_f32_f32_flat(
|
||||
global float * src0,
|
||||
ulong offset0,
|
||||
global float * dst,
|
||||
ulong offsetd,
|
||||
ulong ne,
|
||||
ulong n4
|
||||
) {
|
||||
src0 = (global float*)((global char*)src0 + offset0);
|
||||
dst = (global float*)((global char*)dst + offsetd);
|
||||
|
||||
const ulong i = get_global_id(0);
|
||||
|
||||
if (i < n4) {
|
||||
vstore4(vload4(i, src0), i, dst);
|
||||
} else if (i == n4) {
|
||||
for (ulong t = n4 * 4; t < ne; ++t) {
|
||||
dst[t] = src0[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,871 @@
|
||||
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
|
||||
#pragma OPENCL EXTENSION cl_qcom_subgroup_uniform_load : enable
|
||||
#pragma OPENCL EXTENSION cl_qcom_subgroup_constant_load : enable
|
||||
|
||||
#define bool2 uchar2
|
||||
#define bool3 uchar3
|
||||
#define bool4 uchar4
|
||||
|
||||
__constant sampler_t smp_none = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
|
||||
__constant sampler_t smp_zero = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
|
||||
|
||||
__kernel void adreno_xmem_attn_q_f32_to_img_scaled(const global void * src_void,
|
||||
ulong src_offset,
|
||||
write_only image2d_t dst_image2d,
|
||||
const float scale,
|
||||
const int d_head,
|
||||
const int n_q,
|
||||
const int n_head,
|
||||
const int n_head_kv,
|
||||
const int n_batch,
|
||||
const ulong src_nb1,
|
||||
const ulong src_nb2,
|
||||
const ulong src_nb3) {
|
||||
const int x = get_global_id(0);
|
||||
const int flat_h = get_global_id(1);
|
||||
const int d = get_global_id(2);
|
||||
|
||||
const int heads_total = n_head * n_batch;
|
||||
const int kpack = d_head / 4;
|
||||
|
||||
if (x >= n_q || flat_h >= heads_total || d >= kpack) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int batch = flat_h / n_head;
|
||||
const int head = flat_h % n_head;
|
||||
const int gqa = n_head / n_head_kv;
|
||||
const int head_kv = head / gqa;
|
||||
const int head_group = head - head_kv * gqa;
|
||||
const int compact_h = batch * n_head_kv + head_kv;
|
||||
const int compact_x = head_group * n_q + x;
|
||||
const int c = d * 4;
|
||||
|
||||
const global char * src_base = (const global char *) src_void + src_offset;
|
||||
const global float * row_ptr = (const global float *) (src_base + batch * src_nb3 + head * src_nb2 + x * src_nb1);
|
||||
|
||||
half4 out = (half4) (0.0h);
|
||||
out.x = convert_half(row_ptr[c + 0] * scale);
|
||||
if (c + 1 < d_head) {
|
||||
out.y = convert_half(row_ptr[c + 1] * scale);
|
||||
}
|
||||
if (c + 2 < d_head) {
|
||||
out.z = convert_half(row_ptr[c + 2] * scale);
|
||||
}
|
||||
if (c + 3 < d_head) {
|
||||
out.w = convert_half(row_ptr[c + 3] * scale);
|
||||
}
|
||||
|
||||
write_imageh(dst_image2d, (int2) (compact_x, compact_h * kpack + d), out);
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_kv_f32_to_img_gqa(const global void * src_void,
|
||||
ulong src_offset,
|
||||
write_only image2d_t dst_image2d,
|
||||
const int d_head,
|
||||
const int n_kv,
|
||||
const int n_kv_padded,
|
||||
const int n_head_kv,
|
||||
const int n_batch,
|
||||
const ulong src_nb1,
|
||||
const ulong src_nb2,
|
||||
const ulong src_nb3) {
|
||||
const int x = get_global_id(0);
|
||||
const int flat_h = get_global_id(1);
|
||||
const int d = get_global_id(2);
|
||||
|
||||
const int kv_heads_total = n_head_kv * n_batch;
|
||||
const int kpack = d_head / 4;
|
||||
|
||||
if (x >= n_kv_padded || flat_h >= kv_heads_total || d >= kpack) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int batch = flat_h / n_head_kv;
|
||||
const int head_kv = flat_h % n_head_kv;
|
||||
const int c = d * 4;
|
||||
|
||||
half4 out = (half4) (0.0h);
|
||||
if (x < n_kv) {
|
||||
const global char * src_base = (const global char *) src_void + src_offset;
|
||||
const global float * row_ptr =
|
||||
(const global float *) (src_base + batch * src_nb3 + head_kv * src_nb2 + x * src_nb1);
|
||||
out.x = convert_half(row_ptr[c + 0]);
|
||||
if (c + 1 < d_head) {
|
||||
out.y = convert_half(row_ptr[c + 1]);
|
||||
}
|
||||
if (c + 2 < d_head) {
|
||||
out.z = convert_half(row_ptr[c + 2]);
|
||||
}
|
||||
if (c + 3 < d_head) {
|
||||
out.w = convert_half(row_ptr[c + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
write_imageh(dst_image2d, (int2) (x, flat_h * kpack + d), out);
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_kv_f16_to_img_gqa(const global void * src_void,
|
||||
ulong src_offset,
|
||||
write_only image2d_t dst_image2d,
|
||||
const int d_head,
|
||||
const int n_kv,
|
||||
const int n_kv_padded,
|
||||
const int n_head_kv,
|
||||
const int n_batch,
|
||||
const ulong src_nb1,
|
||||
const ulong src_nb2,
|
||||
const ulong src_nb3) {
|
||||
const int x = get_global_id(0);
|
||||
const int flat_h = get_global_id(1);
|
||||
const int d = get_global_id(2);
|
||||
|
||||
const int kv_heads_total = n_head_kv * n_batch;
|
||||
const int kpack = d_head / 4;
|
||||
|
||||
if (x >= n_kv_padded || flat_h >= kv_heads_total || d >= kpack) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int batch = flat_h / n_head_kv;
|
||||
const int head_kv = flat_h % n_head_kv;
|
||||
const int c = d * 4;
|
||||
|
||||
half4 out = (half4) (0.0h);
|
||||
if (x < n_kv) {
|
||||
const global char * src_base = (const global char *) src_void + src_offset;
|
||||
const global half * row_ptr =
|
||||
(const global half *) (src_base + batch * src_nb3 + head_kv * src_nb2 + x * src_nb1);
|
||||
out.x = row_ptr[c + 0];
|
||||
if (c + 1 < d_head) {
|
||||
out.y = row_ptr[c + 1];
|
||||
}
|
||||
if (c + 2 < d_head) {
|
||||
out.z = row_ptr[c + 2];
|
||||
}
|
||||
if (c + 3 < d_head) {
|
||||
out.w = row_ptr[c + 3];
|
||||
}
|
||||
}
|
||||
|
||||
write_imageh(dst_image2d, (int2) (x, flat_h * kpack + d), out);
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_img_to_f32(global void * dst_void,
|
||||
ulong dst_offset,
|
||||
read_only image2d_t src_image2d,
|
||||
const int d_head,
|
||||
const int n_q,
|
||||
const int n_head,
|
||||
const int n_head_kv,
|
||||
const int n_batch,
|
||||
const ulong dst_nb1,
|
||||
const ulong dst_nb2,
|
||||
const ulong dst_nb3) {
|
||||
const int x = get_global_id(0);
|
||||
const int flat_h = get_global_id(1);
|
||||
const int d = get_global_id(2);
|
||||
|
||||
const int heads_total = n_head * n_batch;
|
||||
const int kpack = d_head / 4;
|
||||
|
||||
if (x >= n_q || flat_h >= heads_total || d >= kpack) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int batch = flat_h / n_head;
|
||||
const int head = flat_h % n_head;
|
||||
const int gqa = n_head / n_head_kv;
|
||||
const int head_kv = head / gqa;
|
||||
const int head_group = head - head_kv * gqa;
|
||||
const int compact_h = batch * n_head_kv + head_kv;
|
||||
const int compact_x = head_group * n_q + x;
|
||||
const int c = d * 4;
|
||||
|
||||
global char * dst_base = (global char *) dst_void + dst_offset;
|
||||
global float * row_ptr = (global float *) (dst_base + batch * dst_nb3 + x * dst_nb2 + head * dst_nb1);
|
||||
|
||||
const half4 in_value = read_imageh(src_image2d, smp_zero, (int2) (compact_x, compact_h * kpack + d));
|
||||
row_ptr[c + 0] = convert_float(in_value.x);
|
||||
if (c + 1 < d_head) {
|
||||
row_ptr[c + 1] = convert_float(in_value.y);
|
||||
}
|
||||
if (c + 2 < d_head) {
|
||||
row_ptr[c + 2] = convert_float(in_value.z);
|
||||
}
|
||||
if (c + 3 < d_head) {
|
||||
row_ptr[c + 3] = convert_float(in_value.w);
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_k_gather(global half4 * dst_tensor_buffer,
|
||||
read_only image2d_t src_tensor_image2d,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1) {
|
||||
int X = get_global_id(0);
|
||||
int Y = get_global_id(1);
|
||||
int S = get_global_id(2);
|
||||
if (X >= shared_int4_0.w || Y >= shared_int4_0.y || S >= shared_int4_0.z) {
|
||||
return;
|
||||
}
|
||||
half temps[4];
|
||||
temps[0] = (half) (0.f);
|
||||
temps[1] = (half) (0.f);
|
||||
temps[2] = (half) (0.f);
|
||||
temps[3] = (half) (0.f);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int dst_channel = S * 4 + i;
|
||||
if (dst_channel < shared_int4_0.x) {
|
||||
int s_y = Y;
|
||||
int s_x = dst_channel;
|
||||
int s_c = X;
|
||||
{
|
||||
int slice_coord_TMP = (s_c) / 4;
|
||||
int sub_ch_coord_TMP = (s_c) % 4;
|
||||
half4 src_TMP = read_imageh(src_tensor_image2d, smp_zero,
|
||||
(int2) ((s_x), ((s_y) *shared_int4_1.x + (slice_coord_TMP))));
|
||||
temps[i] = (half[4]){ src_TMP.x, src_TMP.y, src_TMP.z, src_TMP.w }[sub_ch_coord_TMP];
|
||||
};
|
||||
}
|
||||
}
|
||||
half4 result;
|
||||
result.x = temps[0];
|
||||
result.y = temps[1];
|
||||
result.z = temps[2];
|
||||
result.w = temps[3];
|
||||
dst_tensor_buffer[(((S) *shared_int4_0.y + (Y)) * shared_int4_0.w + (X))] = result;
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_pack_k(global half4 * dst_tensor_buffer,
|
||||
read_only image1d_buffer_t src_image_buffer,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1,
|
||||
const int4 shared_int4_2) {
|
||||
int linear_index = get_global_id(0);
|
||||
if (linear_index >= shared_int4_0.y) {
|
||||
return;
|
||||
}
|
||||
if (get_global_id(1) != 0) {
|
||||
return;
|
||||
}
|
||||
if (get_global_id(2) != 0) {
|
||||
return;
|
||||
}
|
||||
int dst_o_sp_i_ogroup = linear_index;
|
||||
int dst_ogroup = dst_o_sp_i_ogroup % shared_int4_0.x;
|
||||
int dst_o_sp_i = dst_o_sp_i_ogroup / shared_int4_0.x;
|
||||
int dst_i = dst_o_sp_i % shared_int4_0.z;
|
||||
int dst_o_sp = dst_o_sp_i / shared_int4_0.z;
|
||||
int dst_sp = dst_o_sp % shared_int4_1.x;
|
||||
int dst_o = dst_o_sp / shared_int4_1.x;
|
||||
int i_slice = dst_i;
|
||||
int o_slice = dst_o * shared_int4_0.x + dst_ogroup;
|
||||
int spatial_linear = dst_sp;
|
||||
int W = spatial_linear % shared_int4_1.y;
|
||||
int H = spatial_linear / shared_int4_1.y;
|
||||
half4 w0 = (half4) (0);
|
||||
half4 w1 = (half4) (0);
|
||||
half4 w2 = (half4) (0);
|
||||
half4 w3 = (half4) (0);
|
||||
|
||||
if (i_slice * 4 < shared_int4_0.w && o_slice < shared_int4_1.w) {
|
||||
w0 = read_imageh(src_image_buffer, (((o_slice) *shared_int4_1.z + (W)) * shared_int4_2.x + (i_slice * 4)));
|
||||
}
|
||||
if (i_slice * 4 + 1 < shared_int4_0.w && o_slice < shared_int4_1.w) {
|
||||
w1 = read_imageh(src_image_buffer, (((o_slice) *shared_int4_1.z + (W)) * shared_int4_2.x + (i_slice * 4 + 1)));
|
||||
}
|
||||
if (i_slice * 4 + 2 < shared_int4_0.w && o_slice < shared_int4_1.w) {
|
||||
w2 = read_imageh(src_image_buffer, (((o_slice) *shared_int4_1.z + (W)) * shared_int4_2.x + (i_slice * 4 + 2)));
|
||||
}
|
||||
if (i_slice * 4 + 3 < shared_int4_0.w && o_slice < shared_int4_1.w) {
|
||||
w3 = read_imageh(src_image_buffer, (((o_slice) *shared_int4_1.z + (W)) * shared_int4_2.x + (i_slice * 4 + 3)));
|
||||
}
|
||||
half4 r0 = w0;
|
||||
half4 r1 = w1;
|
||||
half4 r2 = w2;
|
||||
half4 r3 = w3;
|
||||
dst_tensor_buffer[linear_index * 4 + 0] = r0;
|
||||
dst_tensor_buffer[linear_index * 4 + 1] = r1;
|
||||
dst_tensor_buffer[linear_index * 4 + 2] = r2;
|
||||
dst_tensor_buffer[linear_index * 4 + 3] = r3;
|
||||
}
|
||||
|
||||
__attribute__((qcom_max_concurrent_subgroups(12))) __kernel void adreno_xmem_attn_qk_gemm(
|
||||
global half4 * dst_tensor_buffer,
|
||||
constant half8 * weights_buffer __attribute__((sub_group_uniform)),
|
||||
constant half8 * xmem_buffer __attribute__((max_constant_size((6144)))),
|
||||
read_only image2d_t src_tensor_image2d,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1,
|
||||
const int4 shared_int4_2) {
|
||||
int X = get_group_id(1) * get_local_size(0) + get_local_id(0);
|
||||
int Y = get_group_id(2) * get_local_size(1) + get_local_id(1);
|
||||
int Z = get_group_id(0) * get_local_size(2) + get_local_id(2);
|
||||
if (X >= shared_int4_0.z || Y >= shared_int4_0.x) {
|
||||
return;
|
||||
}
|
||||
if (Z * 8 >= shared_int4_0.y) {
|
||||
return;
|
||||
}
|
||||
|
||||
half4 r0 = (half4) (0.f);
|
||||
half4 r1 = (half4) (0.f);
|
||||
half4 r2 = (half4) (0.f);
|
||||
half4 r3 = (half4) (0.f);
|
||||
half4 r4 = (half4) (0.f);
|
||||
half4 r5 = (half4) (0.f);
|
||||
half4 r6 = (half4) (0.f);
|
||||
half4 r7 = (half4) (0.f);
|
||||
int x_coord = mad24(X, shared_int4_2.y, shared_int4_1.y);
|
||||
int y_coord = mad24(Y, shared_int4_2.z, shared_int4_1.z);
|
||||
int coord_x, coord_y, coord_s;
|
||||
int f_offset = (Z * shared_int4_1.w + Y) * shared_int4_1.x * 32;
|
||||
|
||||
int subgroup_id = (int) ((0x1F & qcom_get_physical_sub_group_id()));
|
||||
subgroup_id = subgroup_id % 12;
|
||||
int c_offset = mul24(subgroup_id, shared_int4_0.w);
|
||||
__constant half16 * weights_cache = (__constant half16 *) &xmem_buffer[c_offset];
|
||||
coord_y = Y;
|
||||
coord_x = X;
|
||||
coord_s = 0;
|
||||
do {
|
||||
half4 src0 =
|
||||
read_imageh(src_tensor_image2d, smp_zero, (int2) ((coord_x), ((coord_y) *shared_int4_2.x + (coord_s))));
|
||||
coord_s++;
|
||||
half4 src1 =
|
||||
read_imageh(src_tensor_image2d, smp_zero, (int2) ((coord_x), ((coord_y) *shared_int4_2.x + (coord_s))));
|
||||
coord_s++;
|
||||
qcom_sub_group_constant_load8(xmem_buffer, weights_buffer, c_offset, f_offset >> 1, 32);
|
||||
f_offset += 64;
|
||||
qcom_sub_group_sync(QCOM_CLK_CONST_LOAD_SYNC);
|
||||
r0 += src0.x * weights_cache[0].s0123;
|
||||
r0 += src0.y * weights_cache[0].s4567;
|
||||
r0 += src0.z * weights_cache[0].s89ab;
|
||||
r0 += src0.w * weights_cache[0].scdef;
|
||||
r1 += src0.x * weights_cache[1].s0123;
|
||||
r1 += src0.y * weights_cache[1].s4567;
|
||||
r1 += src0.z * weights_cache[1].s89ab;
|
||||
r1 += src0.w * weights_cache[1].scdef;
|
||||
r2 += src0.x * weights_cache[2].s0123;
|
||||
r2 += src0.y * weights_cache[2].s4567;
|
||||
r2 += src0.z * weights_cache[2].s89ab;
|
||||
r2 += src0.w * weights_cache[2].scdef;
|
||||
r3 += src0.x * weights_cache[3].s0123;
|
||||
r3 += src0.y * weights_cache[3].s4567;
|
||||
r3 += src0.z * weights_cache[3].s89ab;
|
||||
r3 += src0.w * weights_cache[3].scdef;
|
||||
r4 += src0.x * weights_cache[4].s0123;
|
||||
r4 += src0.y * weights_cache[4].s4567;
|
||||
r4 += src0.z * weights_cache[4].s89ab;
|
||||
r4 += src0.w * weights_cache[4].scdef;
|
||||
r5 += src0.x * weights_cache[5].s0123;
|
||||
r5 += src0.y * weights_cache[5].s4567;
|
||||
r5 += src0.z * weights_cache[5].s89ab;
|
||||
r5 += src0.w * weights_cache[5].scdef;
|
||||
r6 += src0.x * weights_cache[6].s0123;
|
||||
r6 += src0.y * weights_cache[6].s4567;
|
||||
r6 += src0.z * weights_cache[6].s89ab;
|
||||
r6 += src0.w * weights_cache[6].scdef;
|
||||
r7 += src0.x * weights_cache[7].s0123;
|
||||
r7 += src0.y * weights_cache[7].s4567;
|
||||
r7 += src0.z * weights_cache[7].s89ab;
|
||||
r7 += src0.w * weights_cache[7].scdef;
|
||||
r0 += src1.x * weights_cache[8].s0123;
|
||||
r0 += src1.y * weights_cache[8].s4567;
|
||||
r0 += src1.z * weights_cache[8].s89ab;
|
||||
r0 += src1.w * weights_cache[8].scdef;
|
||||
r1 += src1.x * weights_cache[9].s0123;
|
||||
r1 += src1.y * weights_cache[9].s4567;
|
||||
r1 += src1.z * weights_cache[9].s89ab;
|
||||
r1 += src1.w * weights_cache[9].scdef;
|
||||
r2 += src1.x * weights_cache[10].s0123;
|
||||
r2 += src1.y * weights_cache[10].s4567;
|
||||
r2 += src1.z * weights_cache[10].s89ab;
|
||||
r2 += src1.w * weights_cache[10].scdef;
|
||||
r3 += src1.x * weights_cache[11].s0123;
|
||||
r3 += src1.y * weights_cache[11].s4567;
|
||||
r3 += src1.z * weights_cache[11].s89ab;
|
||||
r3 += src1.w * weights_cache[11].scdef;
|
||||
r4 += src1.x * weights_cache[12].s0123;
|
||||
r4 += src1.y * weights_cache[12].s4567;
|
||||
r4 += src1.z * weights_cache[12].s89ab;
|
||||
r4 += src1.w * weights_cache[12].scdef;
|
||||
r5 += src1.x * weights_cache[13].s0123;
|
||||
r5 += src1.y * weights_cache[13].s4567;
|
||||
r5 += src1.z * weights_cache[13].s89ab;
|
||||
r5 += src1.w * weights_cache[13].scdef;
|
||||
r6 += src1.x * weights_cache[14].s0123;
|
||||
r6 += src1.y * weights_cache[14].s4567;
|
||||
r6 += src1.z * weights_cache[14].s89ab;
|
||||
r6 += src1.w * weights_cache[14].scdef;
|
||||
r7 += src1.x * weights_cache[15].s0123;
|
||||
r7 += src1.y * weights_cache[15].s4567;
|
||||
r7 += src1.z * weights_cache[15].s89ab;
|
||||
r7 += src1.w * weights_cache[15].scdef;
|
||||
} while (coord_s < shared_int4_2.x);
|
||||
|
||||
coord_s = mul24(Z, 8);
|
||||
coord_x = X;
|
||||
coord_y = Y;
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r0);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r1);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r2);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r3);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r4);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r5);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r6);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r7);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image2d, smp_zero, (int2) ((0), ((0) * shared_int4_2.x + (0))));
|
||||
}
|
||||
dst_tensor_buffer[(((coord_s) *shared_int4_0.x + (coord_y)) * shared_int4_0.z + (coord_x))] = res;
|
||||
coord_s++;
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_softmax_reduce_basic(read_only image1d_buffer_t src_tensor_image_buffer,
|
||||
write_only image2d_t dst_tensor_image2d,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1) {
|
||||
int X = get_global_id(0);
|
||||
int Y = get_global_id(1);
|
||||
if (X >= shared_int4_0.z || Y >= shared_int4_0.x) {
|
||||
return;
|
||||
}
|
||||
float sum = 0.0f;
|
||||
int end_channel = shared_int4_0.w;
|
||||
int end_slice = (end_channel + 3) / 4;
|
||||
int start_channel = 0;
|
||||
int start_slice = start_channel / 4;
|
||||
bool need_per_channels_check = start_channel % 4 != 0 || end_channel % 4 != 0;
|
||||
float maximum;
|
||||
{
|
||||
int slice_coord_TMP = (start_channel) / 4;
|
||||
int sub_ch_coord_TMP = (start_channel) % 4;
|
||||
float4 src_TMP = convert_float4(
|
||||
read_imageh(src_tensor_image_buffer, ((slice_coord_TMP) *shared_int4_1.x + (Y)) * shared_int4_1.y + (X)));
|
||||
maximum = (float[4]){ src_TMP.x, src_TMP.y, src_TMP.z, src_TMP.w }[sub_ch_coord_TMP];
|
||||
};
|
||||
for (int d = start_slice; d < end_slice; d += 1) {
|
||||
float4 mask_dot = (float4) (1.f);
|
||||
float4 src =
|
||||
convert_float4(read_imageh(src_tensor_image_buffer, ((d) *shared_int4_1.x + (Y)) * shared_int4_1.y + (X)));
|
||||
if (need_per_channels_check && (d == start_slice || d == end_slice - 1)) {
|
||||
if (d * 4 + 0 < start_channel || d * 4 + 0 >= end_channel) {
|
||||
mask_dot.x = 0.f;
|
||||
src.x = maximum;
|
||||
}
|
||||
if (d * 4 + 1 < start_channel || d * 4 + 1 >= end_channel) {
|
||||
mask_dot.y = 0.f;
|
||||
src.y = maximum;
|
||||
}
|
||||
if (d * 4 + 2 < start_channel || d * 4 + 2 >= end_channel) {
|
||||
mask_dot.z = 0.f;
|
||||
src.z = maximum;
|
||||
}
|
||||
if (d * 4 + 3 < start_channel || d * 4 + 3 >= end_channel) {
|
||||
mask_dot.w = 0.f;
|
||||
src.w = maximum;
|
||||
}
|
||||
}
|
||||
float new_max = max(src.x, src.y);
|
||||
new_max = max(new_max, src.z);
|
||||
new_max = max(new_max, src.w);
|
||||
new_max = max(new_max, maximum);
|
||||
float scale = native_exp(maximum - new_max);
|
||||
maximum = new_max;
|
||||
sum *= scale;
|
||||
float4 exp_res = native_exp(src - maximum);
|
||||
sum += dot(mask_dot, exp_res);
|
||||
}
|
||||
if (!isfinite(maximum) || sum == 0.0f) {
|
||||
write_imageh(dst_tensor_image2d, (int2) (X, Y), (half4) (0.0h));
|
||||
return;
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) (X, Y),
|
||||
(half4) (convert_half(1.0f / sum), convert_half(maximum), 0.0h, 0.0h));
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_softmax_apply_basic(global half4 * dst_tensor_buffer,
|
||||
read_only image1d_buffer_t src_tensor_image_buffer,
|
||||
read_only image2d_t src_tensor_1_image2d,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1) {
|
||||
int X = get_global_id(0);
|
||||
int Y = get_global_id(1);
|
||||
int Z = get_global_id(2);
|
||||
if (X >= shared_int4_0.z || Y >= shared_int4_0.x || Z >= shared_int4_0.y) {
|
||||
return;
|
||||
}
|
||||
half4 src = read_imageh(src_tensor_image_buffer, ((Z) *shared_int4_1.x + (Y)) * shared_int4_1.y + (X));
|
||||
{
|
||||
half4 src_final;
|
||||
{
|
||||
{
|
||||
half4 exp_val = read_imageh(src_tensor_1_image2d, smp_zero, (int2) (X, Y));
|
||||
src_final = exp(src - exp_val.y) * exp_val.x;
|
||||
const int k = Z * 4;
|
||||
const int n_kv = shared_int4_1.z;
|
||||
if (k + 0 >= n_kv) {
|
||||
src_final.x = 0.0h;
|
||||
}
|
||||
if (k + 1 >= n_kv) {
|
||||
src_final.y = 0.0h;
|
||||
}
|
||||
if (k + 2 >= n_kv) {
|
||||
src_final.z = 0.0h;
|
||||
}
|
||||
if (k + 3 >= n_kv) {
|
||||
src_final.w = 0.0h;
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_tensor_buffer[(((Z) *shared_int4_0.x + (Y)) * shared_int4_0.z + (X))] = src_final;
|
||||
};
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_mask_scores(global half4 * dst_score_tensor_buffer,
|
||||
read_only image1d_buffer_t src_score_image_buffer,
|
||||
const global half * mask,
|
||||
const ulong mask_offset,
|
||||
const int q_width,
|
||||
const int n_q,
|
||||
const int n_kv,
|
||||
const int n_kv_padded,
|
||||
const int kv_heads_total,
|
||||
const int n_head,
|
||||
const int n_head_kv,
|
||||
const ulong mask_nb1,
|
||||
const ulong mask_nb2,
|
||||
const ulong mask_nb3,
|
||||
const int mask_ne2,
|
||||
const int mask_ne3) {
|
||||
const int X = get_global_id(0);
|
||||
const int Y = get_global_id(1);
|
||||
const int Z = get_global_id(2);
|
||||
const int npack = n_kv_padded / 4;
|
||||
if (X >= q_width || Y >= kv_heads_total || Z >= npack) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int gqa = n_head / n_head_kv;
|
||||
const int head_kv = Y % n_head_kv;
|
||||
const int batch = Y / n_head_kv;
|
||||
const int head_group = X / n_q;
|
||||
const int q = X - head_group * n_q;
|
||||
const int head = head_kv * gqa + head_group;
|
||||
const int mask_head_idx = head % mask_ne2;
|
||||
const int mask_batch_idx = batch % mask_ne3;
|
||||
const global char * mask_base = (const global char *) mask + mask_offset;
|
||||
const global half * mask_row = (const global half *) (mask_base + mask_batch_idx * mask_nb3 +
|
||||
mask_head_idx * mask_nb2 + q * mask_nb1);
|
||||
|
||||
const half4 score = read_imageh(src_score_image_buffer, ((Z * kv_heads_total + Y) * q_width + X));
|
||||
float vals[4] = {
|
||||
convert_float(score.x),
|
||||
convert_float(score.y),
|
||||
convert_float(score.z),
|
||||
convert_float(score.w),
|
||||
};
|
||||
|
||||
for (int lane = 0; lane < 4; ++lane) {
|
||||
const int k_idx = Z * 4 + lane;
|
||||
if (k_idx >= n_kv) {
|
||||
vals[lane] = -INFINITY;
|
||||
} else {
|
||||
vals[lane] += convert_float(mask_row[k_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
dst_score_tensor_buffer[((Z * kv_heads_total + Y) * q_width + X)] =
|
||||
(half4) (convert_half(vals[0]), convert_half(vals[1]), convert_half(vals[2]), convert_half(vals[3]));
|
||||
}
|
||||
|
||||
__kernel void adreno_xmem_attn_pack_v(global half4 * dst_tensor_buffer,
|
||||
read_only image2d_t src_image2d,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1) {
|
||||
int linear_index = get_global_id(0);
|
||||
if (linear_index >= shared_int4_0.y) {
|
||||
return;
|
||||
}
|
||||
if (get_global_id(1) != 0) {
|
||||
return;
|
||||
}
|
||||
if (get_global_id(2) != 0) {
|
||||
return;
|
||||
}
|
||||
int dst_o_sp_i_ogroup = linear_index;
|
||||
int dst_ogroup = dst_o_sp_i_ogroup % shared_int4_0.x;
|
||||
int dst_o_sp_i = dst_o_sp_i_ogroup / shared_int4_0.x;
|
||||
int dst_i = dst_o_sp_i % shared_int4_0.z;
|
||||
int dst_o_sp = dst_o_sp_i / shared_int4_0.z;
|
||||
int dst_sp = dst_o_sp % shared_int4_1.x;
|
||||
int dst_o = dst_o_sp / shared_int4_1.x;
|
||||
int i_slice = dst_i;
|
||||
int o_slice = dst_o * shared_int4_0.x + dst_ogroup;
|
||||
int spatial_linear = dst_sp;
|
||||
int W = spatial_linear % shared_int4_1.y;
|
||||
int H = spatial_linear / shared_int4_1.y;
|
||||
half4 w0 = (half4) (0);
|
||||
half4 w1 = (half4) (0);
|
||||
half4 w2 = (half4) (0);
|
||||
half4 w3 = (half4) (0);
|
||||
|
||||
if (i_slice * 4 < shared_int4_0.w && o_slice < shared_int4_1.z) {
|
||||
w0 = read_imageh(src_image2d, smp_zero, (int2) ((i_slice * 4), ((W) *shared_int4_1.z + (o_slice))));
|
||||
}
|
||||
if (i_slice * 4 + 1 < shared_int4_0.w && o_slice < shared_int4_1.z) {
|
||||
w1 = read_imageh(src_image2d, smp_zero, (int2) ((i_slice * 4 + 1), ((W) *shared_int4_1.z + (o_slice))));
|
||||
}
|
||||
if (i_slice * 4 + 2 < shared_int4_0.w && o_slice < shared_int4_1.z) {
|
||||
w2 = read_imageh(src_image2d, smp_zero, (int2) ((i_slice * 4 + 2), ((W) *shared_int4_1.z + (o_slice))));
|
||||
}
|
||||
if (i_slice * 4 + 3 < shared_int4_0.w && o_slice < shared_int4_1.z) {
|
||||
w3 = read_imageh(src_image2d, smp_zero, (int2) ((i_slice * 4 + 3), ((W) *shared_int4_1.z + (o_slice))));
|
||||
}
|
||||
half4 r0 = w0;
|
||||
half4 r1 = w1;
|
||||
half4 r2 = w2;
|
||||
half4 r3 = w3;
|
||||
dst_tensor_buffer[linear_index * 4 + 0] = r0;
|
||||
dst_tensor_buffer[linear_index * 4 + 1] = r1;
|
||||
dst_tensor_buffer[linear_index * 4 + 2] = r2;
|
||||
dst_tensor_buffer[linear_index * 4 + 3] = r3;
|
||||
}
|
||||
|
||||
__attribute__((qcom_max_concurrent_subgroups(12))) __kernel void adreno_xmem_attn_pv_gemm(
|
||||
constant half8 * weights_buffer __attribute__((sub_group_uniform)),
|
||||
constant half8 * xmem_buffer __attribute__((max_constant_size((6144)))),
|
||||
read_only image1d_buffer_t src_tensor_image_buffer,
|
||||
write_only image2d_t dst_tensor_image2d,
|
||||
const int4 shared_int4_0,
|
||||
const int4 shared_int4_1,
|
||||
const int4 shared_int4_2,
|
||||
const int4 shared_int4_3) {
|
||||
int X = get_group_id(1) * get_local_size(0) + get_local_id(0);
|
||||
int Y = get_group_id(2) * get_local_size(1) + get_local_id(1);
|
||||
int Z = get_group_id(0) * get_local_size(2) + get_local_id(2);
|
||||
if (X >= shared_int4_0.z || Y >= shared_int4_0.x) {
|
||||
return;
|
||||
}
|
||||
if (Z * 8 >= shared_int4_0.y) {
|
||||
return;
|
||||
}
|
||||
|
||||
half4 r0 = (half4) (0.f);
|
||||
half4 r1 = (half4) (0.f);
|
||||
half4 r2 = (half4) (0.f);
|
||||
half4 r3 = (half4) (0.f);
|
||||
half4 r4 = (half4) (0.f);
|
||||
half4 r5 = (half4) (0.f);
|
||||
half4 r6 = (half4) (0.f);
|
||||
half4 r7 = (half4) (0.f);
|
||||
int x_coord = mad24(X, shared_int4_2.w, shared_int4_1.y);
|
||||
int y_coord = mad24(Y, shared_int4_3.x, shared_int4_1.z);
|
||||
int coord_x, coord_y, coord_s;
|
||||
int f_offset = (Z * shared_int4_1.w + Y) * shared_int4_1.x * 32;
|
||||
|
||||
int subgroup_id = (int) ((0x1F & qcom_get_physical_sub_group_id()));
|
||||
subgroup_id = subgroup_id % 12;
|
||||
int c_offset = mul24(subgroup_id, shared_int4_0.w);
|
||||
__constant half16 * weights_cache = (__constant half16 *) &xmem_buffer[c_offset];
|
||||
coord_y = Y;
|
||||
coord_x = X;
|
||||
int addr = (((0) * shared_int4_1.w + (coord_y)) * shared_int4_2.z + (coord_x));
|
||||
int dz = shared_int4_2.x;
|
||||
coord_s = 0;
|
||||
do {
|
||||
half4 src0 = read_imageh(src_tensor_image_buffer, addr);
|
||||
addr += dz;
|
||||
coord_s++;
|
||||
half4 src1 = read_imageh(src_tensor_image_buffer, addr);
|
||||
addr += dz;
|
||||
coord_s++;
|
||||
qcom_sub_group_constant_load8(xmem_buffer, weights_buffer, c_offset, f_offset >> 1, 32);
|
||||
f_offset += 64;
|
||||
qcom_sub_group_sync(QCOM_CLK_CONST_LOAD_SYNC);
|
||||
r0 += src0.x * weights_cache[0].s0123;
|
||||
r0 += src0.y * weights_cache[0].s4567;
|
||||
r0 += src0.z * weights_cache[0].s89ab;
|
||||
r0 += src0.w * weights_cache[0].scdef;
|
||||
r1 += src0.x * weights_cache[1].s0123;
|
||||
r1 += src0.y * weights_cache[1].s4567;
|
||||
r1 += src0.z * weights_cache[1].s89ab;
|
||||
r1 += src0.w * weights_cache[1].scdef;
|
||||
r2 += src0.x * weights_cache[2].s0123;
|
||||
r2 += src0.y * weights_cache[2].s4567;
|
||||
r2 += src0.z * weights_cache[2].s89ab;
|
||||
r2 += src0.w * weights_cache[2].scdef;
|
||||
r3 += src0.x * weights_cache[3].s0123;
|
||||
r3 += src0.y * weights_cache[3].s4567;
|
||||
r3 += src0.z * weights_cache[3].s89ab;
|
||||
r3 += src0.w * weights_cache[3].scdef;
|
||||
r4 += src0.x * weights_cache[4].s0123;
|
||||
r4 += src0.y * weights_cache[4].s4567;
|
||||
r4 += src0.z * weights_cache[4].s89ab;
|
||||
r4 += src0.w * weights_cache[4].scdef;
|
||||
r5 += src0.x * weights_cache[5].s0123;
|
||||
r5 += src0.y * weights_cache[5].s4567;
|
||||
r5 += src0.z * weights_cache[5].s89ab;
|
||||
r5 += src0.w * weights_cache[5].scdef;
|
||||
r6 += src0.x * weights_cache[6].s0123;
|
||||
r6 += src0.y * weights_cache[6].s4567;
|
||||
r6 += src0.z * weights_cache[6].s89ab;
|
||||
r6 += src0.w * weights_cache[6].scdef;
|
||||
r7 += src0.x * weights_cache[7].s0123;
|
||||
r7 += src0.y * weights_cache[7].s4567;
|
||||
r7 += src0.z * weights_cache[7].s89ab;
|
||||
r7 += src0.w * weights_cache[7].scdef;
|
||||
r0 += src1.x * weights_cache[8].s0123;
|
||||
r0 += src1.y * weights_cache[8].s4567;
|
||||
r0 += src1.z * weights_cache[8].s89ab;
|
||||
r0 += src1.w * weights_cache[8].scdef;
|
||||
r1 += src1.x * weights_cache[9].s0123;
|
||||
r1 += src1.y * weights_cache[9].s4567;
|
||||
r1 += src1.z * weights_cache[9].s89ab;
|
||||
r1 += src1.w * weights_cache[9].scdef;
|
||||
r2 += src1.x * weights_cache[10].s0123;
|
||||
r2 += src1.y * weights_cache[10].s4567;
|
||||
r2 += src1.z * weights_cache[10].s89ab;
|
||||
r2 += src1.w * weights_cache[10].scdef;
|
||||
r3 += src1.x * weights_cache[11].s0123;
|
||||
r3 += src1.y * weights_cache[11].s4567;
|
||||
r3 += src1.z * weights_cache[11].s89ab;
|
||||
r3 += src1.w * weights_cache[11].scdef;
|
||||
r4 += src1.x * weights_cache[12].s0123;
|
||||
r4 += src1.y * weights_cache[12].s4567;
|
||||
r4 += src1.z * weights_cache[12].s89ab;
|
||||
r4 += src1.w * weights_cache[12].scdef;
|
||||
r5 += src1.x * weights_cache[13].s0123;
|
||||
r5 += src1.y * weights_cache[13].s4567;
|
||||
r5 += src1.z * weights_cache[13].s89ab;
|
||||
r5 += src1.w * weights_cache[13].scdef;
|
||||
r6 += src1.x * weights_cache[14].s0123;
|
||||
r6 += src1.y * weights_cache[14].s4567;
|
||||
r6 += src1.z * weights_cache[14].s89ab;
|
||||
r6 += src1.w * weights_cache[14].scdef;
|
||||
r7 += src1.x * weights_cache[15].s0123;
|
||||
r7 += src1.y * weights_cache[15].s4567;
|
||||
r7 += src1.z * weights_cache[15].s89ab;
|
||||
r7 += src1.w * weights_cache[15].scdef;
|
||||
} while (coord_s < shared_int4_2.y);
|
||||
|
||||
coord_s = mul24(Z, 8);
|
||||
coord_x = X;
|
||||
coord_y = Y;
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r0);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r1);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r2);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r3);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r4);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r5);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r6);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
if (coord_s < shared_int4_0.y) {
|
||||
half4 res = convert_half4(r7);
|
||||
if (coord_s < 0) {
|
||||
res += read_imageh(src_tensor_image_buffer, ((0) * shared_int4_1.w + (0)) * shared_int4_2.z + (0));
|
||||
}
|
||||
write_imageh(dst_tensor_image2d, (int2) ((coord_x), ((coord_y) *shared_int4_0.y + (coord_s))), res);
|
||||
coord_s++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Extended elementwise unary ops, same variant shape as abs.cl:
|
||||
// f32, f32_4 (vec4), f16, f16_4 (vec4), f32_nc, f16_nc (stride-addressed).
|
||||
//
|
||||
// sgn, step, elu, hardswish, hardsigmoid, floor, ceil, round, trunc.
|
||||
//
|
||||
// Semantics match the ggml CPU reference (ggml.c). Values are computed in float
|
||||
// (the f16 variants read/write half and convert), so the conditional ops match
|
||||
// the CPU bit-for-bit within tolerance. SEXPR is the scalar form, VEXPR the
|
||||
// float4 form (vector ternaries need select()).
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define UNARY_EXT(NAME, SEXPR, VEXPR) \
|
||||
kernel void kernel_##NAME##_f32( \
|
||||
global const float * src0, ulong offset0, \
|
||||
global float * dst, ulong offsetd) { \
|
||||
src0 = (global float*)((global char*)src0 + offset0); \
|
||||
dst = (global float*)((global char*)dst + offsetd); \
|
||||
float x = src0[get_global_id(0)]; \
|
||||
dst[get_global_id(0)] = (SEXPR); \
|
||||
} \
|
||||
kernel void kernel_##NAME##_f32_4( \
|
||||
global const float4 * src0, ulong offset0, \
|
||||
global float4 * dst, ulong offsetd) { \
|
||||
src0 = (global float4*)((global char*)src0 + offset0); \
|
||||
dst = (global float4*)((global char*)dst + offsetd); \
|
||||
float4 x = src0[get_global_id(0)]; \
|
||||
dst[get_global_id(0)] = (VEXPR); \
|
||||
} \
|
||||
kernel void kernel_##NAME##_f16( \
|
||||
global const half * src0, ulong offset0, \
|
||||
global half * dst, ulong offsetd) { \
|
||||
src0 = (global half*)((global char*)src0 + offset0); \
|
||||
dst = (global half*)((global char*)dst + offsetd); \
|
||||
float x = src0[get_global_id(0)]; \
|
||||
dst[get_global_id(0)] = (SEXPR); \
|
||||
} \
|
||||
kernel void kernel_##NAME##_f16_4( \
|
||||
global const half4 * src0, ulong offset0, \
|
||||
global half4 * dst, ulong offsetd) { \
|
||||
src0 = (global half4*)((global char*)src0 + offset0); \
|
||||
dst = (global half4*)((global char*)dst + offsetd); \
|
||||
float4 x = convert_float4(src0[get_global_id(0)]); \
|
||||
dst[get_global_id(0)] = convert_half4(VEXPR); \
|
||||
} \
|
||||
kernel void kernel_##NAME##_f32_nc( \
|
||||
global const char * src0, ulong offset0, \
|
||||
global char * dst, ulong offsetd, \
|
||||
int ne00, ulong nb00, ulong nb01, ulong nb02, ulong nb03, \
|
||||
ulong nb0, ulong nb1, ulong nb2, ulong nb3) { \
|
||||
src0 = src0 + offset0; dst = dst + offsetd; \
|
||||
const int i3 = get_group_id(2); \
|
||||
const int i2 = get_group_id(1); \
|
||||
const int i1 = get_group_id(0); \
|
||||
for (int i0 = get_local_id(0); i0 < ne00; i0 += get_local_size(0)) { \
|
||||
float x = *(global const float *)(src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00); \
|
||||
*(global float *)(dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0) = (SEXPR); \
|
||||
} \
|
||||
} \
|
||||
kernel void kernel_##NAME##_f16_nc( \
|
||||
global const char * src0, ulong offset0, \
|
||||
global char * dst, ulong offsetd, \
|
||||
int ne00, ulong nb00, ulong nb01, ulong nb02, ulong nb03, \
|
||||
ulong nb0, ulong nb1, ulong nb2, ulong nb3) { \
|
||||
src0 = src0 + offset0; dst = dst + offsetd; \
|
||||
const int i3 = get_group_id(2); \
|
||||
const int i2 = get_group_id(1); \
|
||||
const int i1 = get_group_id(0); \
|
||||
for (int i0 = get_local_id(0); i0 < ne00; i0 += get_local_size(0)) {\
|
||||
float x = *(global const half *)(src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00); \
|
||||
*(global half *)(dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0) = (SEXPR); \
|
||||
} \
|
||||
}
|
||||
|
||||
UNARY_EXT(sgn, sign(x), sign(x))
|
||||
UNARY_EXT(step, x > 0.0f ? 1.0f : 0.0f, select((float4)0.0f, (float4)1.0f, x > 0.0f))
|
||||
UNARY_EXT(elu, x > 0.0f ? x : expm1(x), select(expm1(x), x, x > 0.0f))
|
||||
UNARY_EXT(hardswish, x * fmin(1.0f, fmax(0.0f, (x + 3.0f) / 6.0f)), x * fmin((float4)1.0f, fmax((float4)0.0f, (x + 3.0f) / 6.0f)))
|
||||
UNARY_EXT(hardsigmoid, fmin(1.0f, fmax(0.0f, (x + 3.0f) / 6.0f)), fmin((float4)1.0f, fmax((float4)0.0f, (x + 3.0f) / 6.0f)))
|
||||
UNARY_EXT(floor, floor(x), floor(x))
|
||||
UNARY_EXT(ceil, ceil(x), ceil(x))
|
||||
UNARY_EXT(round, round(x), round(x))
|
||||
UNARY_EXT(trunc, trunc(x), trunc(x))
|
||||
@@ -835,7 +835,7 @@ static size_t ggml_backend_rpc_buffer_type_get_alloc_size(ggml_backend_buffer_ty
|
||||
// [TAG_ALLOC_SIZE_EXPAND]
|
||||
// ops that may require additional memory for fleeting data on certain backends
|
||||
// ref: https://github.com/ggml-org/llama.cpp/pull/15966
|
||||
rpc_get |= ggml_backend_op_alloc_size_may_expand(tensor->op);
|
||||
rpc_get |= ggml_op_alloc_size_may_expand(tensor->op);
|
||||
|
||||
if (rpc_get) {
|
||||
ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
|
||||
|
||||
@@ -94,7 +94,7 @@ static bool ggml_sycl_use_level_zero_device_alloc(sycl::queue &q) {
|
||||
|
||||
// Use Level Zero zeMemAllocDevice to avoid sycl::malloc_device triggering
|
||||
// DMA-buf/TTM system RAM staging in the xe kernel driver during multi-GPU inference.
|
||||
void * ggml_sycl_malloc_device(size_t size, sycl::queue &q) {
|
||||
void * ggml_sycl_malloc_device(size_t size, sycl::queue &q, ggml_sycl_mem_type type) {
|
||||
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
||||
if (ggml_sycl_use_level_zero_device_alloc(q)) {
|
||||
void *ptr = nullptr;
|
||||
@@ -117,16 +117,25 @@ void * ggml_sycl_malloc_device(size_t size, sycl::queue &q) {
|
||||
#endif
|
||||
ze_result_t r = zeMemAllocDevice(ze_ctx, &alloc_desc, size, 64, ze_dev, &ptr);
|
||||
if (r == ZE_RESULT_SUCCESS && ptr) {
|
||||
ggml_sycl_memtrace_add(type, ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
ggml_sycl_memtrace_fail(type, size);
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
return sycl::malloc_device(size, q);
|
||||
void * ptr = sycl::malloc_device(size, q);
|
||||
if (ptr == nullptr) {
|
||||
ggml_sycl_memtrace_fail(type, size);
|
||||
return nullptr;
|
||||
}
|
||||
ggml_sycl_memtrace_add(type, ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void ggml_sycl_free_device(void *ptr, sycl::queue &q) {
|
||||
if (!ptr) return;
|
||||
ggml_sycl_memtrace_del(ptr);
|
||||
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
||||
if (ggml_sycl_use_level_zero_device_alloc(q)) {
|
||||
auto ze_ctx = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q.get_context());
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "type.hpp"
|
||||
#include "sycl_hw.hpp"
|
||||
#include "fattn-buffers.hpp"
|
||||
#include "memtrace.hpp"
|
||||
|
||||
namespace syclexp = sycl::ext::oneapi::experimental;
|
||||
|
||||
@@ -69,6 +70,8 @@ extern int g_ggml_sycl_dev2dev_memcpy;
|
||||
extern int g_ggml_sycl_fa_onednn;
|
||||
extern int g_ggml_sycl_fa_onednn_max_kv;
|
||||
extern int g_ggml_sycl_enable_mkl_fa;
|
||||
extern int g_ggml_sycl_memtrace;
|
||||
extern int g_ggml_sycl_memtrace_step;
|
||||
|
||||
|
||||
#define CHECK_TRY_ERROR(expr) \
|
||||
@@ -318,7 +321,8 @@ struct ggml_tensor_extra_gpu {
|
||||
};
|
||||
|
||||
extern int g_ggml_sycl_use_level_zero_api;
|
||||
void * ggml_sycl_malloc_device(size_t size, sycl::queue &q);
|
||||
void * ggml_sycl_malloc_device(size_t size, sycl::queue &q,
|
||||
ggml_sycl_mem_type type = GGML_SYCL_MEM_DIRECT);
|
||||
void ggml_sycl_free_device(void *ptr, sycl::queue &q);
|
||||
|
||||
void release_extra_gpu(ggml_tensor_extra_gpu * extra, std::vector<queue_ptr> streams={});
|
||||
|
||||
@@ -21,6 +21,7 @@ sycl::half * ggml_sycl_fattn_kv_buffers::kv_buffer::ensure_half(size_t n_elems)
|
||||
|
||||
if (ptr) {
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(qptr->wait()));
|
||||
ggml_sycl_memtrace_del(ptr);
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(sycl::free(ptr, *qptr)));
|
||||
ptr = nullptr;
|
||||
capacity = 0;
|
||||
@@ -38,11 +39,13 @@ sycl::half * ggml_sycl_fattn_kv_buffers::kv_buffer::ensure_half(size_t n_elems)
|
||||
|
||||
if (!dev_ptr) {
|
||||
GGML_LOG_ERROR("%s: can't allocate %lu Bytes of memory on device\n", __func__, cap);
|
||||
ggml_sycl_memtrace_fail(GGML_SYCL_MEM_FATTN_KV, cap);
|
||||
GGML_ABORT("fattn buffer alloc failed");
|
||||
}
|
||||
|
||||
ptr = static_cast<sycl::half *>(dev_ptr);
|
||||
capacity = cap;
|
||||
ggml_sycl_memtrace_add(GGML_SYCL_MEM_FATTN_KV, ptr, cap);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -51,6 +54,7 @@ ggml_sycl_fattn_kv_buffers::kv_buffer::~kv_buffer() {
|
||||
GGML_LOG_INFO("ggml_sycl_fattn_kv_buffer[%d]: %.2f MiB\n", device, capacity / 1024.0 / 1024.0);
|
||||
#endif
|
||||
if (ptr) {
|
||||
ggml_sycl_memtrace_del(ptr);
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(sycl::free(ptr, *qptr)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,50 @@
|
||||
#include "fwht.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#define P 1.0f
|
||||
#define N -1.0f
|
||||
|
||||
// constant Hadamard matrix via Paley I construction
|
||||
static constexpr float H12[12][12] = {
|
||||
{ P, P, P, P, P, P, P, P, P, P, P, P },
|
||||
{ P, N, P, N, P, P, P, N, N, N, P, N },
|
||||
{ P, N, N, P, N, P, P, P, N, N, N, P },
|
||||
{ P, P, N, N, P, N, P, P, P, N, N, N },
|
||||
{ P, N, P, N, N, P, N, P, P, P, N, N },
|
||||
{ P, N, N, P, N, N, P, N, P, P, P, N },
|
||||
{ P, N, N, N, P, N, N, P, N, P, P, P },
|
||||
{ P, P, N, N, N, P, N, N, P, N, P, P },
|
||||
{ P, P, P, N, N, N, P, N, N, P, N, P },
|
||||
{ P, P, P, P, N, N, N, P, N, N, P, N },
|
||||
{ P, N, P, P, P, N, N, N, P, N, N, P },
|
||||
{ P, P, N, P, P, P, N, N, N, P, N, N }
|
||||
};
|
||||
|
||||
static constexpr float H20[20][20] = {
|
||||
{ P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P },
|
||||
{ P, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N },
|
||||
{ P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P },
|
||||
{ P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P },
|
||||
{ P, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N },
|
||||
{ P, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N },
|
||||
{ P, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N },
|
||||
{ P, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N },
|
||||
{ P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P },
|
||||
{ P, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N },
|
||||
{ P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P },
|
||||
{ P, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N },
|
||||
{ P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P },
|
||||
{ P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P },
|
||||
{ P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P },
|
||||
{ P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P },
|
||||
{ P, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N },
|
||||
{ P, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N },
|
||||
{ P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P },
|
||||
{ P, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N }
|
||||
};
|
||||
|
||||
#undef P
|
||||
#undef N
|
||||
|
||||
template <int N>
|
||||
static void fwht_kernel(const float * __restrict__ src, float * __restrict__ dst, const int64_t n_rows,
|
||||
@@ -80,6 +124,122 @@ static void launch_fwht(const float * src, float * dst, const int64_t n_rows, co
|
||||
});
|
||||
}
|
||||
|
||||
template <int N, int m>
|
||||
static void kronecker_kernel(const float * __restrict__ src,
|
||||
float * __restrict__ dst,
|
||||
const int64_t n_rows,
|
||||
const float scale,
|
||||
const sycl::nd_item<2> & item) {
|
||||
static_assert(m == 12 || m == 20, "block size has to be 12 or 20.");
|
||||
|
||||
const sycl::sub_group sg = item.get_sub_group();
|
||||
|
||||
const int64_t r = item.get_global_id(0);
|
||||
if (r >= n_rows) {
|
||||
return;
|
||||
}
|
||||
|
||||
src += r * N;
|
||||
dst += r * N;
|
||||
|
||||
constexpr int blocks_per_group = N / m;
|
||||
constexpr int el_w = blocks_per_group / WARP_SIZE;
|
||||
static_assert(el_w >= 1 && blocks_per_group % WARP_SIZE == 0, "blocks_per_group must be a multiple of WARP_SIZE");
|
||||
float reg[el_w * m];
|
||||
const int lane = sg.get_local_linear_id();
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < el_w; ++i) {
|
||||
const int b_idx = i * WARP_SIZE + lane;
|
||||
|
||||
#pragma unroll
|
||||
for (int j = 0; j < m; ++j) {
|
||||
reg[i * m + j] = src[b_idx * m + j] * scale;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma unroll
|
||||
for (int b = 0; b < el_w; ++b) {
|
||||
float z[m] = { 0.0f };
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < m; ++i) {
|
||||
#pragma unroll
|
||||
for (int j = 0; j < m; ++j) {
|
||||
const float h = (m == 12 ? H12[j][i] : H20[j][i]);
|
||||
z[i] += reg[b * m + j] * h;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < m; ++i) {
|
||||
reg[b * m + i] = z[i];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma unroll
|
||||
for (int h = 1; h < WARP_SIZE; h *= 2) {
|
||||
#pragma unroll
|
||||
for (int j = 0; j < el_w; ++j) {
|
||||
#pragma unroll
|
||||
for (int k = 0; k < m; ++k) {
|
||||
const float val = reg[j * m + k];
|
||||
const float val2 = dpct::permute_sub_group_by_xor(sg, val, h, WARP_SIZE);
|
||||
|
||||
reg[j * m + k] = (lane & h) == 0 ? val + val2 : val2 - val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma unroll
|
||||
for (int h = WARP_SIZE; h < blocks_per_group; h *= 2) {
|
||||
const int step = h / WARP_SIZE;
|
||||
#pragma unroll
|
||||
for (int j = 0; j < el_w; j += 2 * step) {
|
||||
#pragma unroll
|
||||
for (int s = 0; s < step; ++s) {
|
||||
#pragma unroll
|
||||
for (int k = 0; k < m; ++k) {
|
||||
const float x = reg[(j + s) * m + k];
|
||||
const float y = reg[(j + s + step) * m + k];
|
||||
|
||||
reg[(j + s) * m + k] = x + y;
|
||||
reg[(j + s + step) * m + k] = x - y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < el_w; ++i) {
|
||||
const int b_idx = i * WARP_SIZE + lane;
|
||||
#pragma unroll
|
||||
for (int k = 0; k < m; ++k) {
|
||||
dst[b_idx * m + k] = reg[i * m + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <int N, int m>
|
||||
static void launch_kronecker(const float * src,
|
||||
float * dst,
|
||||
const int64_t n_rows,
|
||||
const float scale,
|
||||
dpct::queue_ptr stream) {
|
||||
constexpr int rows_per_block = 4;
|
||||
|
||||
const int64_t num_blocks = (n_rows + rows_per_block - 1) / rows_per_block;
|
||||
|
||||
// dim 1 is the fastest-varying, so a sub-group is exactly one row's WARP_SIZE lanes.
|
||||
const sycl::range<2> global(num_blocks * rows_per_block, WARP_SIZE);
|
||||
const sycl::range<2> local(rows_per_block, WARP_SIZE);
|
||||
|
||||
stream->parallel_for(sycl::nd_range<2>(global, local),
|
||||
[=](sycl::nd_item<2> item) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
|
||||
kronecker_kernel<N, m>(src, dst, n_rows, scale, item);
|
||||
});
|
||||
}
|
||||
|
||||
bool ggml_sycl_op_fwht(ggml_backend_sycl_context & ctx, const ggml_tensor * src, ggml_tensor * dst) {
|
||||
if (src->type != GGML_TYPE_F32 || dst->type != GGML_TYPE_F32) {
|
||||
return false;
|
||||
@@ -113,6 +273,18 @@ bool ggml_sycl_op_fwht(ggml_backend_sycl_context & ctx, const ggml_tensor * src,
|
||||
case 512:
|
||||
launch_fwht<512>(src_d, dst_d, rows, scale, stream);
|
||||
return true;
|
||||
case 384:
|
||||
launch_kronecker<384, 12>(src_d, dst_d, rows, scale, stream);
|
||||
return true;
|
||||
case 768:
|
||||
launch_kronecker<768, 12>(src_d, dst_d, rows, scale, stream);
|
||||
return true;
|
||||
case 640:
|
||||
launch_kronecker<640, 20>(src_d, dst_d, rows, scale, stream);
|
||||
return true;
|
||||
case 1280:
|
||||
launch_kronecker<1280, 20>(src_d, dst_d, rows, scale, stream);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,8 @@ int g_ggml_sycl_enable_dnn = 1;
|
||||
int g_ggml_sycl_fa_onednn = 1;
|
||||
int g_ggml_sycl_fa_onednn_max_kv = 0;
|
||||
int g_ggml_sycl_enable_mkl_fa = 1;
|
||||
int g_ggml_sycl_memtrace = 0;
|
||||
int g_ggml_sycl_memtrace_step = 64;
|
||||
int g_ggml_sycl_enable_vmm = 1;
|
||||
int g_ggml_sycl_enable_fusion = 1;
|
||||
int g_ggml_sycl_enable_esimd = 1;
|
||||
@@ -335,6 +337,8 @@ static void ggml_check_sycl() try {
|
||||
g_ggml_sycl_fa_onednn = ggml_sycl_get_env("GGML_SYCL_FA_ONEDNN", 1);
|
||||
g_ggml_sycl_fa_onednn_max_kv = ggml_sycl_get_env("GGML_SYCL_FA_ONEDNN_MAX_KV", 0);
|
||||
g_ggml_sycl_enable_mkl_fa = ggml_sycl_get_env("GGML_SYCL_ENABLE_MKL_FA", 1);
|
||||
g_ggml_sycl_memtrace = ggml_sycl_get_env("GGML_SYCL_MEMTRACE", 0);
|
||||
g_ggml_sycl_memtrace_step = ggml_sycl_get_env("GGML_SYCL_MEMTRACE_STEP", 64);
|
||||
g_ggml_sycl_enable_vmm = ggml_sycl_get_env("GGML_SYCL_ENABLE_VMM", 1);
|
||||
g_ggml_sycl_enable_fusion = ggml_sycl_get_env("GGML_SYCL_ENABLE_FUSION", 1);
|
||||
g_ggml_sycl_enable_esimd = ggml_sycl_get_env("GGML_SYCL_ENABLE_ESIMD", 1);
|
||||
@@ -421,6 +425,8 @@ static void ggml_check_sycl() try {
|
||||
#endif
|
||||
GGML_LOG_INFO(" GGML_SYCL_FA_ONEDNN_MAX_KV: %d\n", g_ggml_sycl_fa_onednn_max_kv);
|
||||
GGML_LOG_INFO(" GGML_SYCL_ENABLE_MKL_FA: %d\n", g_ggml_sycl_enable_mkl_fa);
|
||||
GGML_LOG_INFO(" GGML_SYCL_MEMTRACE: %d\n", g_ggml_sycl_memtrace);
|
||||
GGML_LOG_INFO(" GGML_SYCL_MEMTRACE_STEP: %d\n", g_ggml_sycl_memtrace_step);
|
||||
#ifdef SYCL_FLASH_ATTN
|
||||
GGML_LOG_INFO(" GGML_SYCL_ENABLE_FLASH_ATTN: %d\n", g_ggml_sycl_enable_flash_attention);
|
||||
#else
|
||||
@@ -964,7 +970,7 @@ ggml_backend_sycl_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft,
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(dev_ptr = (void *)ggml_sycl_malloc_device(size, *stream)));
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(dev_ptr = (void *)ggml_sycl_malloc_device(size, *stream, GGML_SYCL_MEM_BUFFER)));
|
||||
if (!dev_ptr) {
|
||||
GGML_LOG_ERROR("%s: can't allocate %zu Bytes of memory on device\n", __func__, size);
|
||||
return nullptr;
|
||||
@@ -1217,7 +1223,7 @@ ggml_backend_sycl_split_buffer_init_tensor(ggml_backend_buffer_t buffer,
|
||||
ggml_sycl_set_device(i);
|
||||
const queue_ptr stream = ctx->streams[i];
|
||||
char * buf;
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(buf = (char *)ggml_sycl_malloc_device(size, *stream)));
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(buf = (char *)ggml_sycl_malloc_device(size, *stream, GGML_SYCL_MEM_BUFFER)));
|
||||
if (!buf) {
|
||||
char err_buf[1024];
|
||||
snprintf(err_buf, 1023, "%s: can't allocate %zu Bytes of memory on device\n", __func__, size);
|
||||
@@ -1697,7 +1703,7 @@ struct ggml_sycl_pool_leg : public ggml_sycl_pool {
|
||||
void * ptr;
|
||||
size_t look_ahead_size = (size_t) (1.05 * size);
|
||||
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(ptr = (void *)ggml_sycl_malloc_device(look_ahead_size, *qptr)));
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(ptr = (void *)ggml_sycl_malloc_device(look_ahead_size, *qptr, GGML_SYCL_MEM_POOL_LEG)));
|
||||
if (!ptr) {
|
||||
GGML_LOG_ERROR("%s: can't allocate %zu Bytes of memory on device/GPU\n", __func__, look_ahead_size);
|
||||
return nullptr;
|
||||
@@ -1786,6 +1792,13 @@ struct ggml_sycl_pool_vmm : public ggml_sycl_pool {
|
||||
|
||||
GGML_ASSERT(pool_size + reserve_size <= SYCL_POOL_VMM_MAX_SIZE);
|
||||
|
||||
if (ggml_sycl_memtrace_enabled()) {
|
||||
GGML_LOG_INFO(GGML_SYCL_MEMTRACE_TAG " pool_vmm[%d] committing %5zu MiB (pool %5zu -> %5zu MiB)\n",
|
||||
device, reserve_size / (1024 * 1024), pool_size / (1024 * 1024),
|
||||
(pool_size + reserve_size) / (1024 * 1024));
|
||||
ggml_sycl_memtrace_report("before pool_vmm commit");
|
||||
}
|
||||
|
||||
// allocate more physical memory
|
||||
std::optional<sycl::ext::oneapi::experimental::physical_mem> phys;
|
||||
SYCL_CHECK(CHECK_TRY_ERROR(phys.emplace(dev, ctx, reserve_size)));
|
||||
@@ -1811,6 +1824,7 @@ struct ggml_sycl_pool_vmm : public ggml_sycl_pool {
|
||||
|
||||
// add to the pool
|
||||
pool_size += reserve_size;
|
||||
ggml_sycl_memtrace_add(GGML_SYCL_MEM_POOL_VMM, map_ptr, reserve_size);
|
||||
|
||||
#ifdef DEBUG_SYCL_MALLOC
|
||||
GGML_LOG_INFO("sycl pool[%d]: size increased to %llu MB (reserved %llu MB)\n",
|
||||
@@ -4039,7 +4053,9 @@ static inline void * sycl_ext_malloc_device(dpct::queue_ptr stream, size_t size)
|
||||
bool use_async = g_ggml_sycl_use_async_mem_op;
|
||||
#if defined(GGML_SYCL_GRAPH) && SYCL_EXT_ONEAPI_ASYNC_MEMORY_ALLOC
|
||||
if (use_async) {
|
||||
return syclex::async_malloc(*stream, sycl::usm::alloc::device, size);
|
||||
void * ptr = syclex::async_malloc(*stream, sycl::usm::alloc::device, size);
|
||||
ggml_sycl_memtrace_add(GGML_SYCL_MEM_ASYNC, ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
#else
|
||||
// If async allocation extension is not available, use_async should always be false.
|
||||
@@ -4052,6 +4068,7 @@ static inline void sycl_ext_free(dpct::queue_ptr stream, void * ptr) {
|
||||
bool use_async = g_ggml_sycl_use_async_mem_op;
|
||||
#if defined(GGML_SYCL_GRAPH) && SYCL_EXT_ONEAPI_ASYNC_MEMORY_ALLOC
|
||||
if (use_async) {
|
||||
ggml_sycl_memtrace_del(ptr);
|
||||
syclex::async_free(*stream, ptr);
|
||||
return;
|
||||
}
|
||||
@@ -5643,6 +5660,7 @@ void ggml_backend_sycl_get_device_memory(int device, size_t * free, size_t * tot
|
||||
if (!res) {
|
||||
GGML_ABORT("[%s] failed to get device memory size", __func__);
|
||||
}
|
||||
ggml_sycl_memtrace_report_device("device memory query", device, *free, *total);
|
||||
} catch (const sycl::exception & exc) {
|
||||
std::cerr << exc.what() << "Exception caught at file:" << __FILE__ << ", line:" << __LINE__ << std::endl;
|
||||
std::exit(1);
|
||||
@@ -6082,6 +6100,7 @@ static void ggml_backend_sycl_device_get_memory(ggml_backend_dev_t dev, size_t *
|
||||
if (!res) {
|
||||
GGML_ABORT("[%s] failed to get device memory size", __func__);
|
||||
}
|
||||
ggml_sycl_memtrace_report_device("device memory query (dev)", ctx->device, *free, *total);
|
||||
}
|
||||
|
||||
static enum ggml_backend_dev_type ggml_backend_sycl_device_get_type(ggml_backend_dev_t dev) {
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "memtrace.hpp"
|
||||
|
||||
#include "common.hpp"
|
||||
#include "ggml-impl.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
constexpr size_t MIB = 1024 * 1024;
|
||||
|
||||
static const char * mem_type_name(ggml_sycl_mem_type type) {
|
||||
switch (type) {
|
||||
case GGML_SYCL_MEM_BUFFER: return "buffer";
|
||||
case GGML_SYCL_MEM_POOL_LEG: return "pool_leg";
|
||||
case GGML_SYCL_MEM_POOL_VMM: return "pool_vmm";
|
||||
case GGML_SYCL_MEM_ASYNC: return "async";
|
||||
case GGML_SYCL_MEM_FATTN_KV: return "fattn_kv";
|
||||
case GGML_SYCL_MEM_DIRECT: return "direct";
|
||||
default: GGML_ABORT("[%s] The type value %d is not supported\n", __func__, (int) type);
|
||||
}
|
||||
}
|
||||
|
||||
struct mem_tracker {
|
||||
std::mutex mutex;
|
||||
std::unordered_map<const void *, std::pair<ggml_sycl_mem_type, size_t>> live_by_ptr;
|
||||
size_t live[GGML_SYCL_MEM_TYPE_COUNT] = {};
|
||||
size_t peak[GGML_SYCL_MEM_TYPE_COUNT] = {};
|
||||
size_t total_live = 0;
|
||||
size_t total_peak = 0;
|
||||
size_t last_logged_peak = 0;
|
||||
};
|
||||
|
||||
static mem_tracker & get_tracker() {
|
||||
static mem_tracker t;
|
||||
return t;
|
||||
}
|
||||
|
||||
static size_t step_bytes() {
|
||||
const int mib = g_ggml_sycl_memtrace_step > 0 ? g_ggml_sycl_memtrace_step : 64;
|
||||
return (size_t) mib * MIB;
|
||||
}
|
||||
|
||||
static void report_sites_locked() {
|
||||
mem_tracker & t = get_tracker();
|
||||
for (int i = 0; i < GGML_SYCL_MEM_TYPE_COUNT; i++) {
|
||||
if (t.peak[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
GGML_LOG_INFO(GGML_SYCL_MEMTRACE_TAG " %-9s allocated %5zu MiB, peak %5zu MiB\n",
|
||||
mem_type_name((ggml_sycl_mem_type) i), t.live[i] / MIB, t.peak[i] / MIB);
|
||||
}
|
||||
}
|
||||
|
||||
static void report_locked(const char * tag) {
|
||||
mem_tracker & t = get_tracker();
|
||||
|
||||
const size_t allocated = t.total_live / MIB;
|
||||
const size_t buffers = t.live[GGML_SYCL_MEM_BUFFER] / MIB;
|
||||
|
||||
GGML_LOG_INFO(GGML_SYCL_MEMTRACE_TAG " %s: allocated %5zu MiB (buffers %5zu + scratch %5zu),"
|
||||
" peak %5zu MiB\n",
|
||||
tag, allocated, buffers, allocated - buffers, t.total_peak / MIB);
|
||||
report_sites_locked();
|
||||
}
|
||||
|
||||
static void log_event_locked(const char * op, ggml_sycl_mem_type type, const void * ptr, size_t bytes) {
|
||||
GGML_LOG_INFO(GGML_SYCL_MEMTRACE_TAG " allocated %5zu MiB %-5s %-9s %9.3f MiB ptr=%p\n",
|
||||
get_tracker().total_live / MIB, op, mem_type_name(type),
|
||||
(double) bytes / MIB, ptr);
|
||||
}
|
||||
|
||||
bool ggml_sycl_memtrace_enabled() {
|
||||
return g_ggml_sycl_memtrace > 0;
|
||||
}
|
||||
|
||||
void ggml_sycl_memtrace_add(ggml_sycl_mem_type type, const void * ptr, size_t bytes) {
|
||||
if (!ggml_sycl_memtrace_enabled()) {
|
||||
return;
|
||||
}
|
||||
GGML_ASSERT(ptr != nullptr);
|
||||
GGML_ASSERT(bytes != 0);
|
||||
|
||||
mem_tracker & t = get_tracker();
|
||||
std::lock_guard<std::mutex> lock(t.mutex);
|
||||
|
||||
auto it = t.live_by_ptr.find(ptr);
|
||||
if (it != t.live_by_ptr.end()) {
|
||||
t.live[it->second.first] -= it->second.second;
|
||||
t.total_live -= it->second.second;
|
||||
}
|
||||
|
||||
t.live_by_ptr[ptr] = { type, bytes };
|
||||
t.live[type] += bytes;
|
||||
t.total_live += bytes;
|
||||
|
||||
if (t.live[type] > t.peak[type]) {
|
||||
t.peak[type] = t.live[type];
|
||||
}
|
||||
if (t.total_live > t.total_peak) {
|
||||
t.total_peak = t.total_live;
|
||||
}
|
||||
|
||||
if (g_ggml_sycl_memtrace >= 2) {
|
||||
log_event_locked("alloc", type, ptr, bytes);
|
||||
}
|
||||
|
||||
static const size_t step = step_bytes();
|
||||
if (t.total_peak >= t.last_logged_peak + step) {
|
||||
t.last_logged_peak = t.total_peak;
|
||||
char tag[96];
|
||||
std::snprintf(tag, sizeof(tag), "peak grew (+%zu MiB from %s)", bytes / MIB,
|
||||
mem_type_name(type));
|
||||
report_locked(tag);
|
||||
}
|
||||
}
|
||||
|
||||
void ggml_sycl_memtrace_del(const void * ptr) {
|
||||
if (!ggml_sycl_memtrace_enabled() || ptr == nullptr) {
|
||||
return;
|
||||
}
|
||||
mem_tracker & t = get_tracker();
|
||||
std::lock_guard<std::mutex> lock(t.mutex);
|
||||
|
||||
auto it = t.live_by_ptr.find(ptr);
|
||||
if (it == t.live_by_ptr.end()) {
|
||||
return;
|
||||
}
|
||||
const ggml_sycl_mem_type type = it->second.first;
|
||||
const size_t bytes = it->second.second;
|
||||
t.live[type] -= bytes;
|
||||
t.total_live -= bytes;
|
||||
t.live_by_ptr.erase(it);
|
||||
|
||||
if (g_ggml_sycl_memtrace >= 2) {
|
||||
log_event_locked("free", type, ptr, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void ggml_sycl_memtrace_fail(ggml_sycl_mem_type type, size_t bytes) {
|
||||
GGML_LOG_ERROR(GGML_SYCL_MEMTRACE_TAG " alloc FAILED: %9.3f MiB %s\n",
|
||||
(double) bytes / MIB, mem_type_name(type));
|
||||
if (!ggml_sycl_memtrace_enabled()) {
|
||||
return;
|
||||
}
|
||||
mem_tracker & t = get_tracker();
|
||||
std::lock_guard<std::mutex> lock(t.mutex);
|
||||
report_locked("at allocation failure");
|
||||
}
|
||||
|
||||
void ggml_sycl_memtrace_report(const char * tag) {
|
||||
if (!ggml_sycl_memtrace_enabled()) {
|
||||
return;
|
||||
}
|
||||
mem_tracker & t = get_tracker();
|
||||
std::lock_guard<std::mutex> lock(t.mutex);
|
||||
report_locked(tag);
|
||||
}
|
||||
|
||||
static bool device_memory_is_dedicated(int device) {
|
||||
if (device < 0 || device >= ggml_sycl_info().device_count) {
|
||||
return false;
|
||||
}
|
||||
const sycl_device_info & info = ggml_sycl_info().devices[device];
|
||||
return info.l0_device_type_valid && info.l0_discrete_gpu;
|
||||
}
|
||||
|
||||
void ggml_sycl_memtrace_report_device(const char * tag, int device, size_t dev_free, size_t dev_total) {
|
||||
if (!ggml_sycl_memtrace_enabled()) {
|
||||
return;
|
||||
}
|
||||
mem_tracker & t = get_tracker();
|
||||
std::lock_guard<std::mutex> lock(t.mutex);
|
||||
|
||||
const size_t in_use = dev_total > dev_free ? dev_total - dev_free : 0;
|
||||
const size_t total = dev_total / MIB;
|
||||
const size_t freed = dev_free / MIB;
|
||||
const size_t allocated = t.total_live / MIB;
|
||||
const size_t buffers = t.live[GGML_SYCL_MEM_BUFFER] / MIB;
|
||||
const size_t peak = t.total_peak / MIB;
|
||||
|
||||
if (in_use >= t.total_live && device_memory_is_dedicated(device) && total >= freed + allocated) {
|
||||
GGML_LOG_INFO(GGML_SYCL_MEMTRACE_TAG " %s: total %5zu MiB = free %5zu + allocated %5zu"
|
||||
" (buffers %5zu + scratch %5zu) + other %5zu, peak %5zu MiB\n",
|
||||
tag, total, freed, allocated, buffers, allocated - buffers,
|
||||
total - freed - allocated, peak);
|
||||
} else {
|
||||
GGML_LOG_INFO(GGML_SYCL_MEMTRACE_TAG " %s: total %5zu MiB, free %5zu, in use %5zu;"
|
||||
" allocated %5zu (buffers %5zu + scratch %5zu), peak %5zu MiB\n",
|
||||
tag, total, freed, in_use / MIB, allocated, buffers,
|
||||
allocated - buffers, peak);
|
||||
}
|
||||
report_sites_locked();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef GGML_SYCL_MEMTRACE_HPP
|
||||
#define GGML_SYCL_MEMTRACE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#define GGML_SYCL_MEMTRACE_TAG "[SYCL-MEMTRACE]"
|
||||
|
||||
enum ggml_sycl_mem_type {
|
||||
GGML_SYCL_MEM_BUFFER = 0,
|
||||
GGML_SYCL_MEM_POOL_LEG,
|
||||
GGML_SYCL_MEM_POOL_VMM,
|
||||
GGML_SYCL_MEM_ASYNC,
|
||||
GGML_SYCL_MEM_FATTN_KV,
|
||||
GGML_SYCL_MEM_DIRECT,
|
||||
|
||||
GGML_SYCL_MEM_TYPE_COUNT,
|
||||
};
|
||||
|
||||
bool ggml_sycl_memtrace_enabled();
|
||||
|
||||
void ggml_sycl_memtrace_add(ggml_sycl_mem_type type, const void * ptr, size_t bytes);
|
||||
void ggml_sycl_memtrace_del(const void * ptr);
|
||||
|
||||
void ggml_sycl_memtrace_report(const char * tag);
|
||||
void ggml_sycl_memtrace_report_device(const char * tag, int device, size_t dev_free, size_t dev_total);
|
||||
void ggml_sycl_memtrace_fail(ggml_sycl_mem_type type, size_t bytes);
|
||||
|
||||
#endif // GGML_SYCL_MEMTRACE_HPP
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define GGML_VERSION "@GGML_VERSION@"
|
||||
#define GGML_COMMIT "@GGML_BUILD_COMMIT@"
|
||||
@@ -1,6 +1,7 @@
|
||||
#define _CRT_SECURE_NO_DEPRECATE // Disables "unsafe" warnings on Windows
|
||||
#define _USE_MATH_DEFINES // For M_PI on MSVC
|
||||
|
||||
#include "ggml-version.h"
|
||||
#include "ggml-backend.h"
|
||||
#include "ggml-impl.h"
|
||||
#include "ggml-threading.h"
|
||||
|
||||
@@ -230,6 +230,8 @@ class Keys:
|
||||
COUNT = "{arch}.hyper_connection.count"
|
||||
SINKHORN_ITERATIONS = "{arch}.hyper_connection.sinkhorn_iterations"
|
||||
EPSILON = "{arch}.hyper_connection.epsilon"
|
||||
# scale of the post gate (DeepSeek-V4 hardcodes 2.0)
|
||||
MAGNITUDE = "{arch}.hyper_connection.magnitude"
|
||||
# absent means the mix projection is full rank (DeepSeek-V4 behaviour)
|
||||
LOW_RANK = "{arch}.hyper_connection.low_rank"
|
||||
|
||||
@@ -592,6 +594,7 @@ class MODEL_ARCH(IntEnum):
|
||||
HUNYUAN_DENSE = auto()
|
||||
HUNYUAN_VL = auto()
|
||||
HY_V3 = auto()
|
||||
HY_V4 = auto()
|
||||
SMOLLM3 = auto()
|
||||
GPT_OSS = auto()
|
||||
LFM2 = auto()
|
||||
@@ -1345,6 +1348,7 @@ MODEL_ARCH_NAMES: dict[MODEL_ARCH, str] = {
|
||||
MODEL_ARCH.HUNYUAN_DENSE: "hunyuan-dense",
|
||||
MODEL_ARCH.HUNYUAN_VL: "hunyuan_vl",
|
||||
MODEL_ARCH.HY_V3: "hy_v3",
|
||||
MODEL_ARCH.HY_V4: "hy_v4",
|
||||
MODEL_ARCH.SMOLLM3: "smollm3",
|
||||
MODEL_ARCH.GPT_OSS: "gpt-oss",
|
||||
MODEL_ARCH.LFM2: "lfm2",
|
||||
@@ -4739,6 +4743,48 @@ MODEL_TENSORS: dict[MODEL_ARCH, list[MODEL_TENSOR]] = {
|
||||
MODEL_TENSOR.NEXTN_SHARED_HEAD_HEAD,
|
||||
MODEL_TENSOR.NEXTN_SHARED_HEAD_NORM,
|
||||
],
|
||||
MODEL_ARCH.HY_V4: [
|
||||
MODEL_TENSOR.TOKEN_EMBD,
|
||||
MODEL_TENSOR.OUTPUT_NORM,
|
||||
MODEL_TENSOR.OUTPUT,
|
||||
MODEL_TENSOR.ROPE_FREQS,
|
||||
MODEL_TENSOR.HC_HEAD_FN,
|
||||
MODEL_TENSOR.HC_HEAD_BASE,
|
||||
MODEL_TENSOR.HC_HEAD_SCALE,
|
||||
MODEL_TENSOR.ATTN_NORM,
|
||||
MODEL_TENSOR.ATTN_SINKS,
|
||||
MODEL_TENSOR.ATTN_Q_A,
|
||||
MODEL_TENSOR.ATTN_Q_A_NORM,
|
||||
MODEL_TENSOR.ATTN_Q_B,
|
||||
MODEL_TENSOR.ATTN_KV_A_MQA,
|
||||
MODEL_TENSOR.ATTN_KV_A_NORM,
|
||||
MODEL_TENSOR.ATTN_K_B,
|
||||
MODEL_TENSOR.ATTN_V_B,
|
||||
MODEL_TENSOR.ATTN_OUT,
|
||||
MODEL_TENSOR.ATTN_GATE,
|
||||
MODEL_TENSOR.INDEXER_K_NORM,
|
||||
MODEL_TENSOR.INDEXER_PROJ,
|
||||
MODEL_TENSOR.INDEXER_ATTN_K,
|
||||
MODEL_TENSOR.INDEXER_ATTN_Q_B,
|
||||
MODEL_TENSOR.HC_ATTN_FN,
|
||||
MODEL_TENSOR.HC_ATTN_BASE,
|
||||
MODEL_TENSOR.HC_ATTN_SCALE,
|
||||
MODEL_TENSOR.HC_FFN_FN,
|
||||
MODEL_TENSOR.HC_FFN_BASE,
|
||||
MODEL_TENSOR.HC_FFN_SCALE,
|
||||
MODEL_TENSOR.FFN_GATE_INP,
|
||||
MODEL_TENSOR.FFN_EXP_PROBS_B,
|
||||
MODEL_TENSOR.FFN_NORM,
|
||||
MODEL_TENSOR.FFN_GATE,
|
||||
MODEL_TENSOR.FFN_DOWN,
|
||||
MODEL_TENSOR.FFN_UP,
|
||||
MODEL_TENSOR.FFN_GATE_EXP,
|
||||
MODEL_TENSOR.FFN_DOWN_EXP,
|
||||
MODEL_TENSOR.FFN_UP_EXP,
|
||||
MODEL_TENSOR.FFN_GATE_SHEXP,
|
||||
MODEL_TENSOR.FFN_DOWN_SHEXP,
|
||||
MODEL_TENSOR.FFN_UP_SHEXP,
|
||||
],
|
||||
MODEL_ARCH.SMOLLM3: [
|
||||
MODEL_TENSOR.TOKEN_EMBD,
|
||||
MODEL_TENSOR.OUTPUT_NORM,
|
||||
@@ -5438,6 +5484,10 @@ MODEL_TENSOR_SKIP: dict[MODEL_ARCH, list[MODEL_TENSOR]] = {
|
||||
MODEL_TENSOR.ROPE_FREQS,
|
||||
MODEL_TENSOR.ATTN_ROT_EMBD,
|
||||
],
|
||||
MODEL_ARCH.HY_V4: [
|
||||
MODEL_TENSOR.ROPE_FREQS,
|
||||
MODEL_TENSOR.ATTN_ROT_EMBD,
|
||||
],
|
||||
MODEL_ARCH.CHATGLM: [
|
||||
MODEL_TENSOR.ROPE_FREQS,
|
||||
],
|
||||
|
||||
@@ -1055,6 +1055,9 @@ class GGUFWriter:
|
||||
def add_hyper_connection_epsilon(self, value: float) -> None:
|
||||
self.add_float32(Keys.HyperConnection.EPSILON.format(arch=self.arch), value)
|
||||
|
||||
def add_hyper_connection_magnitude(self, value: float) -> None:
|
||||
self.add_float32(Keys.HyperConnection.MAGNITUDE.format(arch=self.arch), value)
|
||||
|
||||
def add_hyper_connection_low_rank(self, value: int) -> None:
|
||||
self.add_uint32(Keys.HyperConnection.LOW_RANK.format(arch=self.arch), value)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
36da57138425487184aa1da2eee2cde155909c6f
|
||||
e91ded11bdcd78c42f9c8d3978ff6686eb4c1226
|
||||
|
||||
@@ -121,6 +121,7 @@ static const std::map<llm_arch, const char *> LLM_ARCH_NAMES = {
|
||||
{ LLM_ARCH_HUNYUAN_DENSE, "hunyuan-dense" },
|
||||
{ LLM_ARCH_HUNYUAN_VL, "hunyuan_vl" },
|
||||
{ LLM_ARCH_HY_V3, "hy_v3" },
|
||||
{ LLM_ARCH_HY_V4, "hy_v4" },
|
||||
{ LLM_ARCH_SMOLLM3, "smollm3" },
|
||||
{ LLM_ARCH_OPENAI_MOE, "gpt-oss" },
|
||||
{ LLM_ARCH_LFM2, "lfm2" },
|
||||
@@ -294,6 +295,7 @@ static const std::map<llm_kv, const char *> LLM_KV_NAMES = {
|
||||
{ LLM_KV_HYPER_CONNECTION_COUNT, "%s.hyper_connection.count" },
|
||||
{ LLM_KV_HYPER_CONNECTION_SINKHORN_ITERATIONS, "%s.hyper_connection.sinkhorn_iterations" },
|
||||
{ LLM_KV_HYPER_CONNECTION_EPSILON, "%s.hyper_connection.epsilon" },
|
||||
{ LLM_KV_HYPER_CONNECTION_MAGNITUDE, "%s.hyper_connection.magnitude" },
|
||||
{ LLM_KV_HYPER_CONNECTION_LOW_RANK, "%s.hyper_connection.low_rank" },
|
||||
|
||||
{ LLM_KV_PLE_LAYERS, "%s.ple.layers" },
|
||||
@@ -1130,6 +1132,7 @@ bool llm_arch_supports_sm_tensor(const llm_arch & arch) {
|
||||
case LLM_ARCH_OLMOE:
|
||||
case LLM_ARCH_DEEPSEEK2:
|
||||
case LLM_ARCH_DEEPSEEK32:
|
||||
case LLM_ARCH_HY_V4:
|
||||
case LLM_ARCH_DOTS3NOTE:
|
||||
case LLM_ARCH_GLM_DSA:
|
||||
case LLM_ARCH_BITNET:
|
||||
|
||||
@@ -126,6 +126,7 @@ enum llm_arch {
|
||||
LLM_ARCH_HUNYUAN_DENSE,
|
||||
LLM_ARCH_HUNYUAN_VL,
|
||||
LLM_ARCH_HY_V3,
|
||||
LLM_ARCH_HY_V4,
|
||||
LLM_ARCH_SMOLLM3,
|
||||
LLM_ARCH_OPENAI_MOE,
|
||||
LLM_ARCH_LFM2,
|
||||
@@ -299,6 +300,7 @@ enum llm_kv {
|
||||
LLM_KV_HYPER_CONNECTION_COUNT,
|
||||
LLM_KV_HYPER_CONNECTION_SINKHORN_ITERATIONS,
|
||||
LLM_KV_HYPER_CONNECTION_EPSILON,
|
||||
LLM_KV_HYPER_CONNECTION_MAGNITUDE,
|
||||
LLM_KV_HYPER_CONNECTION_LOW_RANK,
|
||||
|
||||
LLM_KV_PLE_LAYERS,
|
||||
|
||||
@@ -2317,7 +2317,8 @@ uint32_t llama_context::graph_max_nodes(uint32_t n_tokens) const {
|
||||
(model.arch == LLM_ARCH_DFLASH && model.hparams.dsv4_hc_mult > 0) ||
|
||||
model.arch == LLM_ARCH_NANBEIGE ||
|
||||
model.arch == LLM_ARCH_MINIMAX_01 ||
|
||||
model.arch == LLM_ARCH_MINIMAX_M3) {
|
||||
model.arch == LLM_ARCH_MINIMAX_M3 ||
|
||||
model.arch == LLM_ARCH_HY_V4) {
|
||||
res = std::max<uint32_t>(n_tokens * 40, 32u * model.n_tensors());
|
||||
} else if (model.arch == LLM_ARCH_DFLASH && model.hparams.dflash_selector_rank > 0) {
|
||||
// DFlash2's convolutions and selector are shape work rather than matmuls,
|
||||
|
||||
+5
-2
@@ -566,7 +566,10 @@ void llm_graph_input_attn_k_dsa::set_input(const llama_ubatch * ubatch) {
|
||||
|
||||
mctx->get_lid()->set_input_kq_mask(self_kq_mask_lid, ubatch, cparams.causal_attn);
|
||||
|
||||
mctx->get_lid()->set_input_k_rot(self_k_rot_lid);
|
||||
// left unallocated when the indexer does not use the rotation
|
||||
if (self_k_rot_lid && self_k_rot_lid->buffer) {
|
||||
mctx->get_lid()->set_input_k_rot(self_k_rot_lid);
|
||||
}
|
||||
}
|
||||
|
||||
bool llm_graph_input_attn_k_dsa::can_reuse(const llm_graph_params & params) {
|
||||
@@ -2170,7 +2173,7 @@ ggml_tensor * llm_graph_context::build_moe_ffn(
|
||||
const float limit = hparams.swiglu_clamp_exp[il];
|
||||
constexpr float eps = 1e-6f;
|
||||
if (limit > eps) {
|
||||
if (arch == LLM_ARCH_DEEPSEEK4 || (arch == LLM_ARCH_DFLASH && hparams.dsv4_hc_mult > 0)) {
|
||||
if (arch == LLM_ARCH_DEEPSEEK4 || (arch == LLM_ARCH_DFLASH && hparams.dsv4_hc_mult > 0) || arch == LLM_ARCH_HY_V4) {
|
||||
cur = ggml_swiglu_clamp(ctx0, cur, up, limit);
|
||||
} else {
|
||||
up = ggml_clamp(ctx0, up, -limit, limit);
|
||||
|
||||
@@ -87,6 +87,15 @@ uint32_t llama_hparams::n_expert_used(uint32_t il) const {
|
||||
GGML_ABORT("fatal error");
|
||||
}
|
||||
|
||||
uint32_t llama_hparams::n_expert_used_max() const {
|
||||
uint32_t val = 0;
|
||||
for (uint32_t il = 0; il < n_layer_all; ++il) {
|
||||
val = std::max(val, n_expert_used(il));
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t llama_hparams::n_gqa(uint32_t il) const {
|
||||
const uint32_t n_head = this->n_head(il);
|
||||
const uint32_t n_head_kv = this->n_head_kv(il);
|
||||
|
||||
+17
-3
@@ -28,6 +28,14 @@ enum llama_swa_type {
|
||||
LLAMA_SWA_TYPE_SYMMETRIC = 3,
|
||||
};
|
||||
|
||||
// how the non-causal mask should be constructed with llama_set_causal_attn(ctx, false)
|
||||
// (e.g. mtmd decoding image tokens)
|
||||
enum llama_non_causal_type {
|
||||
LLAMA_NON_CAUSAL_TYPE_ALL = 0, // all layers non-causal, SWA still applied (gemma 3, qwen-vl, ...)
|
||||
LLAMA_NON_CAUSAL_TYPE_SWA_ONLY = 1, // SWA layers non-causal, dense layers stay causal (gemma 4)
|
||||
LLAMA_NON_CAUSAL_TYPE_SWA_FULL = 2, // all layers non-causal, SWA not applied between tokens of the current ubatch (deepseek 4)
|
||||
};
|
||||
|
||||
// forward declaration; full definition in llama-graph.h
|
||||
enum llm_ffn_op_type : int;
|
||||
|
||||
@@ -164,9 +172,9 @@ struct llama_hparams {
|
||||
// the size of the sliding window (0 - no SWA)
|
||||
uint32_t n_swa = 0;
|
||||
|
||||
// deepseek4 vision: when decoding non-causally (multimodal input), SWA is not applied between tokens of the current ubatch (the image span); older tokens are still window-clipped
|
||||
// for other models (like gemma 3, gemma 4): SWA is always applied to match transformers implementation
|
||||
bool swa_full_non_causal = false;
|
||||
// see llama_non_causal_type
|
||||
// note: for SWA_FULL, older tokens (outside the current ubatch) are still window-clipped
|
||||
llama_non_causal_type non_causal_type = LLAMA_NON_CAUSAL_TYPE_ALL;
|
||||
|
||||
// if is_swa_impl[il] == 1, then layer il is SWA
|
||||
// if is_swa_impl[il] == 0, then layer il is dense (i.e. non-SWA)
|
||||
@@ -289,6 +297,9 @@ struct llama_hparams {
|
||||
// 0 = full rank (DeepSeek-V4)
|
||||
uint32_t hc_low_rank = 0;
|
||||
|
||||
// scale of the hyper-connection post gate (DeepSeek-V4 hardcodes 2.0)
|
||||
float hc_magnitude = 0.0f;
|
||||
|
||||
uint32_t ple_ngram_size = 0;
|
||||
uint32_t ple_heads_per_ngram = 0;
|
||||
uint32_t ple_conv_kernel = 0;
|
||||
@@ -392,6 +403,9 @@ struct llama_hparams {
|
||||
|
||||
uint32_t n_expert_used(uint32_t il = 0) const;
|
||||
|
||||
// return the maximum n_expert_used across all layers
|
||||
uint32_t n_expert_used_max() const;
|
||||
|
||||
uint32_t n_gqa(uint32_t il = 0) const;
|
||||
|
||||
uint32_t n_rot(uint32_t il = 0) const;
|
||||
|
||||
@@ -1681,8 +1681,8 @@ static void set_input_kq_mask_impl(const args_set_input_kq_mask & args, T * data
|
||||
|
||||
// apply SWA if any
|
||||
if (swa) {
|
||||
// see llama_hparams::swa_full_non_causal
|
||||
const bool in_span = !causal && args.hparams.swa_full_non_causal && p0 >= seq_pos_min[seq_id];
|
||||
// see llama_non_causal_type
|
||||
const bool in_span = !causal && args.hparams.non_causal_type == LLAMA_NON_CAUSAL_TYPE_SWA_FULL && p0 >= seq_pos_min[seq_id];
|
||||
if (!in_span && llama_hparams::is_masked_swa(n_swa, swa_type, p0, p1)) {
|
||||
goto skip;
|
||||
}
|
||||
@@ -1754,6 +1754,12 @@ void llama_kv_cache::set_input_kq_mask(ggml_tensor * dst, const llama_ubatch * u
|
||||
// n_tps == n_tokens_per_stream
|
||||
const int64_t n_tps = n_tokens/n_stream;
|
||||
|
||||
// see llama_non_causal_type
|
||||
// only the SWA cache (or the SWA layers of a single cache) become non-causal
|
||||
if (!causal_attn && hparams.non_causal_type == LLAMA_NON_CAUSAL_TYPE_SWA_ONLY) {
|
||||
causal_attn = swa_type == LLAMA_SWA_TYPE_NONE;
|
||||
}
|
||||
|
||||
//const int64_t t_start = ggml_time_us();
|
||||
|
||||
const args_set_input_kq_mask args = {
|
||||
|
||||
@@ -951,7 +951,7 @@ static bool weight_buft_supported(const llama_hparams & hparams, ggml_tensor * w
|
||||
case GGML_OP_MUL_MAT_ID:
|
||||
{
|
||||
// Used for either MoE expert routing or embedded adapter routing
|
||||
const int n_ids_used = hparams.router_layer >= 0 ? 1 : hparams.n_expert_used();
|
||||
const int n_ids_used = hparams.router_layer >= 0 ? 1 : hparams.n_expert_used_max();
|
||||
GGML_ASSERT(n_ids_used > 0);
|
||||
ggml_tensor * b = ggml_new_tensor_3d(ctx, GGML_TYPE_F32, w->ne[0], n_ids_used, 512);
|
||||
ggml_tensor * ids = ggml_new_tensor_2d(ctx, GGML_TYPE_I32, n_ids_used, 512);
|
||||
@@ -964,7 +964,7 @@ static bool weight_buft_supported(const llama_hparams & hparams, ggml_tensor * w
|
||||
} break;
|
||||
case GGML_OP_ADD_ID:
|
||||
{
|
||||
const int n_expert_used = hparams.n_expert_used();
|
||||
const int n_expert_used = hparams.n_expert_used_max();
|
||||
GGML_ASSERT(n_expert_used > 0);
|
||||
ggml_tensor * a = ggml_new_tensor_3d(ctx, GGML_TYPE_F32, w->ne[0], n_expert_used, 512);
|
||||
ggml_tensor * c = ggml_new_tensor_2d(ctx, GGML_TYPE_I32, n_expert_used, 512);
|
||||
|
||||
@@ -314,6 +314,7 @@ void llama_model_saver::add_kv_from_model() {
|
||||
add_kv(LLM_KV_HYPER_CONNECTION_COUNT, hparams.dsv4_hc_mult);
|
||||
add_kv(LLM_KV_HYPER_CONNECTION_SINKHORN_ITERATIONS, hparams.dsv4_hc_sinkhorn_iters);
|
||||
add_kv(LLM_KV_HYPER_CONNECTION_EPSILON, hparams.dsv4_hc_eps);
|
||||
add_kv(LLM_KV_HYPER_CONNECTION_MAGNITUDE, hparams.hc_magnitude);
|
||||
add_kv(LLM_KV_HASH_LAYER_COUNT, hparams.dsv4_hash_layer_count);
|
||||
add_kv(LLM_KV_HYPER_CONNECTION_LOW_RANK, hparams.hc_low_rank);
|
||||
|
||||
|
||||
+52
-8
@@ -288,6 +288,8 @@ static llama_model * llama_model_mapping(llm_arch arch, const llama_model_params
|
||||
return new llama_model_hunyuan_dense(params);
|
||||
case LLM_ARCH_HY_V3:
|
||||
return new llama_model_hy_v3(params);
|
||||
case LLM_ARCH_HY_V4:
|
||||
return new llama_model_hy_v4(params);
|
||||
case LLM_ARCH_SMOLLM3:
|
||||
return new llama_model_smollm3(params);
|
||||
case LLM_ARCH_OPENAI_MOE:
|
||||
@@ -1254,10 +1256,7 @@ void llama_model_base::load_hparams(llama_model_loader & ml) {
|
||||
}
|
||||
|
||||
// models may route a different number of experts per layer, so validate the maximum
|
||||
uint32_t n_expert_used_max = 0;
|
||||
for (uint32_t il = 0; il < hparams.n_layer_all; ++il) {
|
||||
n_expert_used_max = std::max(n_expert_used_max, hparams.n_expert_used(il));
|
||||
}
|
||||
uint32_t n_expert_used_max = hparams.n_expert_used_max();
|
||||
|
||||
GGML_ASSERT(hparams.n_expert <= LLAMA_MAX_EXPERTS);
|
||||
GGML_ASSERT(n_expert_used_max <= hparams.n_expert);
|
||||
@@ -1509,10 +1508,9 @@ bool llama_model_base::load_tensors(llama_model_loader & ml) {
|
||||
// TODO: move to a separate function
|
||||
const auto tn = LLM_TN(arch);
|
||||
|
||||
const int64_t n_expert = hparams.n_expert;
|
||||
const int64_t n_expert_used = hparams.n_expert_used();
|
||||
const int64_t n_expert = hparams.n_expert;
|
||||
|
||||
if (n_expert > 0 && n_expert_used == 0) {
|
||||
if (n_expert > 0 && hparams.n_expert_used_max() == 0) {
|
||||
throw std::runtime_error("model has expert layers but no expert layers are used");
|
||||
}
|
||||
|
||||
@@ -1960,6 +1958,7 @@ void llama_model::print_info() const {
|
||||
LLAMA_LOG_INFO("%s: n_rot = %u\n", __func__, hparams.n_rot_full);
|
||||
LLAMA_LOG_INFO("%s: n_swa = %u\n", __func__, hparams.n_swa);
|
||||
LLAMA_LOG_INFO("%s: is_swa_any = %u\n", __func__, hparams.is_swa_any());
|
||||
LLAMA_LOG_INFO("%s: non_causal_type = %d\n", __func__, hparams.non_causal_type);
|
||||
LLAMA_LOG_INFO("%s: n_embd_head_k = %u\n", __func__, hparams.n_embd_head_k_full);
|
||||
LLAMA_LOG_INFO("%s: n_embd_head_v = %u\n", __func__, hparams.n_embd_head_v_full);
|
||||
LLAMA_LOG_INFO("%s: n_gqa = %s\n", __func__, print_f([&](uint32_t il) { return hparams.n_gqa(il); }, hparams.n_layer_all).c_str());
|
||||
@@ -2056,7 +2055,8 @@ void llama_model::print_info() const {
|
||||
|
||||
if (arch == LLM_ARCH_DEEPSEEK2 || arch == LLM_ARCH_DEEPSEEK2OCR ||
|
||||
arch == LLM_ARCH_DEEPSEEK32 || arch == LLM_ARCH_GLM_DSA ||
|
||||
arch == LLM_ARCH_DOTS3NOTE || arch == LLM_ARCH_MISTRAL4) {
|
||||
arch == LLM_ARCH_DOTS3NOTE || arch == LLM_ARCH_MISTRAL4 ||
|
||||
arch == LLM_ARCH_HY_V4) {
|
||||
LLAMA_LOG_INFO("%s: n_layer_dense_lead = %d\n", __func__, hparams.n_layer_dense_lead);
|
||||
LLAMA_LOG_INFO("%s: n_lora_q = %d\n", __func__, hparams.n_lora_q);
|
||||
LLAMA_LOG_INFO("%s: n_lora_kv = %d\n", __func__, hparams.n_lora_kv);
|
||||
@@ -2325,6 +2325,48 @@ llama_memory_i * llama_model::create_memory(const llama_memory_params & params,
|
||||
nullptr);
|
||||
}
|
||||
} break;
|
||||
case LLM_ARCH_HY_V4:
|
||||
{
|
||||
if (hparams.indexer_top_k == 0) {
|
||||
// full-attention checkpoint: no indexer, so no indexer key cache
|
||||
res = new llama_kv_cache(
|
||||
*this,
|
||||
hparams,
|
||||
params.type_k,
|
||||
params.type_v,
|
||||
!cparams.flash_attn,
|
||||
cparams.offload_kqv,
|
||||
cparams.kv_unified,
|
||||
cparams.n_ctx_seq,
|
||||
cparams.n_seq_max,
|
||||
1,
|
||||
hparams.n_swa,
|
||||
hparams.swa_type,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
} else {
|
||||
// only "full" layers own an indexer, so the shared layers need no indexer cache
|
||||
llama_kv_cache::layer_filter_cb filter_lid = [&](uint32_t il) { return hparams.is_indexer_full(il); };
|
||||
|
||||
res = new llama_kv_cache_dsa(
|
||||
*this,
|
||||
params.type_k,
|
||||
params.type_v,
|
||||
!cparams.flash_attn,
|
||||
cparams.offload_kqv,
|
||||
cparams.kv_unified,
|
||||
cparams.n_ctx_seq,
|
||||
cparams.n_seq_max,
|
||||
1,
|
||||
hparams.n_swa,
|
||||
hparams.swa_type,
|
||||
nullptr,
|
||||
filter_lid,
|
||||
nullptr);
|
||||
}
|
||||
} break;
|
||||
case LLM_ARCH_DOTS3NOTE:
|
||||
{
|
||||
GGML_ASSERT(hparams.swa_type != LLAMA_SWA_TYPE_NONE);
|
||||
@@ -2884,6 +2926,8 @@ llama_rope_type llama_model_rope_type(const llama_model * model) {
|
||||
case LLM_ARCH_DOTS3NOTE:
|
||||
case LLM_ARCH_NANBEIGE:
|
||||
case LLM_ARCH_POCKETTTS:
|
||||
// HY_V4 rotates consecutive pairs, matching the reference implementation
|
||||
case LLM_ARCH_HY_V4:
|
||||
return LLAMA_ROPE_TYPE_NORM;
|
||||
|
||||
// the pairs of head values are offset by n_rot/2
|
||||
|
||||
@@ -318,6 +318,7 @@ struct llm_tokenizer_bpe : llm_tokenizer {
|
||||
case LLAMA_VOCAB_PRE_TYPE_DEEPSEEK3_LLM:
|
||||
case LLAMA_VOCAB_PRE_TYPE_HUNYUAN_DENSE:
|
||||
case LLAMA_VOCAB_PRE_TYPE_JOYAI_LLM:
|
||||
case LLAMA_VOCAB_PRE_TYPE_HY_V4:
|
||||
regex_exprs = {
|
||||
"\\p{N}{1,3}",
|
||||
"[一-龥-ゟ゠-ヿ]+",
|
||||
@@ -2350,6 +2351,10 @@ void llama_vocab::impl::load(llama_model_loader & ml, const LLM_KV & kv) {
|
||||
tokenizer_pre == "hunyuan-dense") {
|
||||
pre_type = LLAMA_VOCAB_PRE_TYPE_HUNYUAN_DENSE;
|
||||
clean_spaces = false;
|
||||
} else if (
|
||||
tokenizer_pre == "hy_v4") {
|
||||
pre_type = LLAMA_VOCAB_PRE_TYPE_HY_V4;
|
||||
clean_spaces = false;
|
||||
} else if (
|
||||
tokenizer_pre == "joyai-llm") {
|
||||
pre_type = LLAMA_VOCAB_PRE_TYPE_JOYAI_LLM;
|
||||
|
||||
@@ -65,6 +65,7 @@ enum llama_vocab_pre_type {
|
||||
LLAMA_VOCAB_PRE_TYPE_GRANITE_EMB_MULTI = 54,
|
||||
LLAMA_VOCAB_PRE_TYPE_MELLUM2 = 55,
|
||||
LLAMA_VOCAB_PRE_TYPE_LAGUNA = 56,
|
||||
LLAMA_VOCAB_PRE_TYPE_HY_V4 = 57,
|
||||
};
|
||||
|
||||
struct LLM_KV;
|
||||
|
||||
@@ -68,7 +68,7 @@ void llama_model_deepseek4::load_arch_hparams(llama_model_loader & ml) {
|
||||
hparams.set_swa_pattern(0);
|
||||
// tokens of an image span attend bidirectionally to the whole span, the window only applies to older tokens
|
||||
// ref: get_window_topk_idxs_visible in the reference impl
|
||||
hparams.swa_full_non_causal = true;
|
||||
hparams.non_causal_type = LLAMA_NON_CAUSAL_TYPE_SWA_FULL;
|
||||
for (uint32_t il = hparams.n_layer(); il < hparams.n_layer_all; ++il) {
|
||||
hparams.is_swa_impl[il] = true;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@ void llama_model_gemma4::load_arch_hparams(llama_model_loader & ml) {
|
||||
ml.get_key(LLM_KV_ATTENTION_VALUE_LENGTH_SWA, hparams.n_embd_head_v_swa);
|
||||
ml.get_key(LLM_KV_FINAL_LOGIT_SOFTCAPPING, hparams.f_final_logit_softcapping, false);
|
||||
|
||||
// when non_causal is set, the model will use bidirectional attention on SWA layers only, while dense layers will remain causal
|
||||
// ref: use_bidirectional_attention == "vision" in HF config
|
||||
// note: E2B/E4B are always causal, bypassing this logic
|
||||
hparams.non_causal_type = LLAMA_NON_CAUSAL_TYPE_SWA_ONLY;
|
||||
|
||||
switch (hparams.n_layer()) {
|
||||
case 30: type = LLM_TYPE_26B_A4B; break;
|
||||
case 35: type = LLM_TYPE_E2B; break;
|
||||
|
||||
@@ -0,0 +1,601 @@
|
||||
#include "models.h"
|
||||
|
||||
#include "llama-kv-cache.h"
|
||||
#include "llama-kv-cache-dsa.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
// iHC (independent Hyper-Connections) helpers. Same layout as the DeepSeek-V4 HC, but without
|
||||
// the comb/sinkhorn term: hc_fn makes only 2*hc coefficients (pre + post). The streams mix
|
||||
// through the pre-reduce / post-distribute round trip instead.
|
||||
|
||||
static size_t hy_v4_elem_offset(const ggml_tensor * t, int64_t i) {
|
||||
return ggml_row_size(t->type, i);
|
||||
}
|
||||
|
||||
static ggml_tensor * hy_v4_view_1d(ggml_context * ctx, ggml_tensor * t, int64_t ne0, int64_t i0) {
|
||||
return ggml_view_1d(ctx, t, ne0, hy_v4_elem_offset(t, i0));
|
||||
}
|
||||
|
||||
static ggml_tensor * hy_v4_view_2d(ggml_context * ctx, ggml_tensor * t, int64_t ne0, int64_t ne1, int64_t i0) {
|
||||
return ggml_view_2d(ctx, t, ne0, ne1, t->nb[1], hy_v4_elem_offset(t, i0));
|
||||
}
|
||||
|
||||
void llama_model_hy_v4::load_arch_hparams(llama_model_loader & ml) {
|
||||
ml.get_key(LLM_KV_ATTENTION_LAYERNORM_RMS_EPS, hparams.f_norm_rms_eps);
|
||||
ml.get_key(LLM_KV_LEADING_DENSE_BLOCK_COUNT, hparams.n_layer_dense_lead, false);
|
||||
ml.get_key(LLM_KV_ATTENTION_Q_LORA_RANK, hparams.n_lora_q);
|
||||
ml.get_key(LLM_KV_ATTENTION_KV_LORA_RANK, hparams.n_lora_kv);
|
||||
ml.get_key(LLM_KV_ATTENTION_KEY_LENGTH_MLA, hparams.n_embd_head_k_mla_impl);
|
||||
ml.get_key(LLM_KV_ATTENTION_VALUE_LENGTH_MLA, hparams.n_embd_head_v_mla_impl);
|
||||
ml.get_key_or_arr(LLM_KV_EXPERT_FEED_FORWARD_LENGTH, hparams.n_ff_exp_arr, hparams.n_layer_all);
|
||||
ml.get_key(LLM_KV_EXPERT_SHARED_COUNT, hparams.n_expert_shared);
|
||||
ml.get_key(LLM_KV_EXPERT_WEIGHTS_SCALE, hparams.expert_weights_scale, false);
|
||||
ml.get_key(LLM_KV_EXPERT_WEIGHTS_NORM, hparams.expert_weights_norm, false);
|
||||
ml.get_key(LLM_KV_EXPERT_GATING_FUNC, hparams.expert_gating_func, false);
|
||||
|
||||
// routed-expert SwiGLU logits clamp (shared/dense experts are NOT clamped, so
|
||||
// swiglu_clamp_shexp is intentionally left at its 0 default)
|
||||
ml.get_key_or_arr(LLM_KV_SWIGLU_CLAMP_EXP, hparams.swiglu_clamp_exp, hparams.n_layer_all, false);
|
||||
|
||||
ml.get_key(LLM_KV_HYPER_CONNECTION_COUNT, hparams.dsv4_hc_mult);
|
||||
ml.get_key(LLM_KV_HYPER_CONNECTION_EPSILON, hparams.dsv4_hc_eps);
|
||||
ml.get_key(LLM_KV_HYPER_CONNECTION_MAGNITUDE, hparams.hc_magnitude);
|
||||
|
||||
// DSA is absent on the all-full_attention checkpoints, so indexer_top_k stays 0 there
|
||||
ml.get_key(LLM_KV_ATTENTION_INDEXER_HEAD_COUNT, hparams.indexer_n_head, false);
|
||||
ml.get_key(LLM_KV_ATTENTION_INDEXER_KEY_LENGTH, hparams.indexer_head_size, false);
|
||||
ml.get_key(LLM_KV_ATTENTION_INDEXER_TOP_K, hparams.indexer_top_k, false);
|
||||
|
||||
if (hparams.indexer_top_k > 0) {
|
||||
// the reference plumbs rms_norm_eps into the indexer k_norm LayerNorm, and build_norm
|
||||
// reads f_norm_eps for LLM_NORM
|
||||
hparams.f_norm_eps = hparams.f_norm_rms_eps;
|
||||
|
||||
if (hparams.indexer_n_head == 0 || hparams.indexer_head_size <= hparams.n_rot()) {
|
||||
throw std::runtime_error("hy_v4: bad indexer head count / key length");
|
||||
}
|
||||
|
||||
ml.get_key_or_arr(LLM_KV_ATTENTION_INDEXER_TYPES, hparams.is_indexer_full_impl, hparams.n_layer(), false);
|
||||
if (!hparams.is_indexer_full(0)) {
|
||||
throw std::runtime_error("hy_v4: layer 0 must own an indexer, nothing precedes it to share");
|
||||
}
|
||||
}
|
||||
|
||||
GGML_ASSERT(hparams.is_mla());
|
||||
|
||||
type = LLM_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
void llama_model_hy_v4::load_arch_tensors(llama_model_loader &) {
|
||||
LLAMA_LOAD_LOCALS;
|
||||
|
||||
const int64_t n_embd_head_k_mla = hparams.n_embd_head_k_mla();
|
||||
const int64_t n_embd_head_v_mla = hparams.n_embd_head_v_mla();
|
||||
const int64_t n_embd_head_qk_rope = hparams.n_rot();
|
||||
const int64_t n_embd_head_qk_nope = n_embd_head_k_mla - n_embd_head_qk_rope;
|
||||
GGML_ASSERT(n_embd_head_qk_nope >= 1);
|
||||
|
||||
const int64_t q_lora_rank = hparams.n_lora_q;
|
||||
const int64_t kv_lora_rank = hparams.n_lora_kv;
|
||||
const int64_t n_ff_exp = hparams.n_ff_exp();
|
||||
const int64_t n_expert_shared = hparams.n_expert_shared;
|
||||
const int64_t hc = hparams.dsv4_hc_mult;
|
||||
|
||||
tok_embd = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), {n_embd, n_vocab}, 0);
|
||||
output_norm = create_tensor(tn(LLM_TENSOR_OUTPUT_NORM, "weight"), {n_embd}, 0);
|
||||
output = create_tensor(tn(LLM_TENSOR_OUTPUT, "weight"), {n_embd, n_vocab}, 0);
|
||||
|
||||
// global iHC head (collapses hc streams before the final norm)
|
||||
hc_head_fn = create_tensor(tn(LLM_TENSOR_HC_HEAD_FN, "weight"), {hc * n_embd, hc}, 0);
|
||||
hc_head_base = create_tensor(tn(LLM_TENSOR_HC_HEAD_BASE, "weight"), {hc}, 0);
|
||||
hc_head_scale = create_tensor(tn(LLM_TENSOR_HC_HEAD_SCALE, "weight"), {1}, 0);
|
||||
|
||||
for (int i = 0; i < n_layer; ++i) {
|
||||
auto & layer = layers[i];
|
||||
|
||||
layer.attn_norm = create_tensor(tn(LLM_TENSOR_ATTN_NORM, "weight", i), {n_embd}, 0);
|
||||
layer.attn_sinks = create_tensor(tn(LLM_TENSOR_ATTN_SINKS, "weight", i), {n_head}, 0);
|
||||
|
||||
layer.wq_a = create_tensor(tn(LLM_TENSOR_ATTN_Q_A, "weight", i), {n_embd, q_lora_rank}, 0);
|
||||
layer.attn_q_a_norm = create_tensor(tn(LLM_TENSOR_ATTN_Q_A_NORM, "weight", i), {q_lora_rank}, 0);
|
||||
layer.wq_b = create_tensor(tn(LLM_TENSOR_ATTN_Q_B, "weight", i), {q_lora_rank, n_head * n_embd_head_k_mla}, 0);
|
||||
layer.wkv_a_mqa = create_tensor(tn(LLM_TENSOR_ATTN_KV_A_MQA, "weight", i), {n_embd, kv_lora_rank + n_embd_head_qk_rope}, 0);
|
||||
layer.attn_kv_a_norm= create_tensor(tn(LLM_TENSOR_ATTN_KV_A_NORM,"weight", i), {kv_lora_rank}, 0);
|
||||
layer.wk_b = create_tensor(tn(LLM_TENSOR_ATTN_K_B, "weight", i), {n_embd_head_qk_nope, kv_lora_rank, n_head}, 0);
|
||||
layer.wv_b = create_tensor(tn(LLM_TENSOR_ATTN_V_B, "weight", i), {kv_lora_rank, n_embd_head_v_mla, n_head}, 0);
|
||||
layer.wo = create_tensor(tn(LLM_TENSOR_ATTN_OUT, "weight", i), {n_head * n_embd_head_v_mla, n_embd}, 0);
|
||||
layer.wqkv_gate = create_tensor(tn(LLM_TENSOR_ATTN_GATE, "weight", i), {n_embd, n_head * n_embd_head_v_mla}, 0);
|
||||
|
||||
// only "full" indexer layers ship weights; "shared" layers reuse their top-k
|
||||
if (hparams.indexer_top_k > 0 && hparams.is_indexer_full(i)) {
|
||||
const int64_t n_indexer_head = hparams.indexer_n_head;
|
||||
const int64_t n_embd_indexer = hparams.indexer_head_size;
|
||||
|
||||
layer.indexer_attn_q_b = create_tensor(tn(LLM_TENSOR_INDEXER_ATTN_Q_B, "weight", i), {q_lora_rank, n_indexer_head * n_embd_indexer}, 0);
|
||||
layer.indexer_attn_k = create_tensor(tn(LLM_TENSOR_INDEXER_ATTN_K, "weight", i), {n_embd, n_embd_indexer}, 0);
|
||||
layer.indexer_k_norm = create_tensor(tn(LLM_TENSOR_INDEXER_K_NORM, "weight", i), {n_embd_indexer}, 0);
|
||||
layer.indexer_k_norm_b = create_tensor(tn(LLM_TENSOR_INDEXER_K_NORM, "bias", i), {n_embd_indexer}, 0);
|
||||
layer.indexer_proj = create_tensor(tn(LLM_TENSOR_INDEXER_PROJ, "weight", i), {n_embd, n_indexer_head}, 0);
|
||||
}
|
||||
|
||||
layer.hc_attn_fn = create_tensor(tn(LLM_TENSOR_HC_ATTN_FN, "weight", i), {hc * n_embd, 2 * hc}, 0);
|
||||
layer.hc_attn_base = create_tensor(tn(LLM_TENSOR_HC_ATTN_BASE, "weight", i), {2 * hc}, 0);
|
||||
layer.hc_attn_scale = create_tensor(tn(LLM_TENSOR_HC_ATTN_SCALE, "weight", i), {2}, 0);
|
||||
layer.hc_ffn_fn = create_tensor(tn(LLM_TENSOR_HC_FFN_FN, "weight", i), {hc * n_embd, 2 * hc}, 0);
|
||||
layer.hc_ffn_base = create_tensor(tn(LLM_TENSOR_HC_FFN_BASE, "weight", i), {2 * hc}, 0);
|
||||
layer.hc_ffn_scale = create_tensor(tn(LLM_TENSOR_HC_FFN_SCALE, "weight", i), {2}, 0);
|
||||
|
||||
layer.ffn_norm = create_tensor(tn(LLM_TENSOR_FFN_NORM, "weight", i), {n_embd}, 0);
|
||||
|
||||
if (i < (int) hparams.n_layer_dense_lead) {
|
||||
layer.ffn_gate = create_tensor(tn(LLM_TENSOR_FFN_GATE, "weight", i), {n_embd, n_ff}, 0);
|
||||
layer.ffn_down = create_tensor(tn(LLM_TENSOR_FFN_DOWN, "weight", i), { n_ff, n_embd}, 0);
|
||||
layer.ffn_up = create_tensor(tn(LLM_TENSOR_FFN_UP, "weight", i), {n_embd, n_ff}, 0);
|
||||
} else {
|
||||
layer.ffn_gate_inp = create_tensor(tn(LLM_TENSOR_FFN_GATE_INP, "weight", i), {n_embd, n_expert}, 0);
|
||||
layer.ffn_exp_probs_b = create_tensor(tn(LLM_TENSOR_FFN_EXP_PROBS_B, "bias", i), {n_expert}, TENSOR_NOT_REQUIRED);
|
||||
|
||||
if (n_expert == 0) {
|
||||
throw std::runtime_error("n_expert must be > 0");
|
||||
}
|
||||
if (n_expert_used == 0) {
|
||||
throw std::runtime_error("n_expert_used must be > 0");
|
||||
}
|
||||
|
||||
layer.ffn_gate_exps = create_tensor(tn(LLM_TENSOR_FFN_GATE_EXPS, "weight", i), {n_embd, n_ff_exp, n_expert}, 0);
|
||||
layer.ffn_up_exps = create_tensor(tn(LLM_TENSOR_FFN_UP_EXPS, "weight", i), {n_embd, n_ff_exp, n_expert}, 0);
|
||||
layer.ffn_down_exps = create_tensor(tn(LLM_TENSOR_FFN_DOWN_EXPS, "weight", i), {n_ff_exp, n_embd, n_expert}, 0);
|
||||
|
||||
layer.ffn_gate_shexp = create_tensor(tn(LLM_TENSOR_FFN_GATE_SHEXP, "weight", i), {n_embd, n_ff_exp * n_expert_shared}, 0);
|
||||
layer.ffn_down_shexp = create_tensor(tn(LLM_TENSOR_FFN_DOWN_SHEXP, "weight", i), {n_ff_exp * n_expert_shared, n_embd}, 0);
|
||||
layer.ffn_up_shexp = create_tensor(tn(LLM_TENSOR_FFN_UP_SHEXP, "weight", i), {n_embd, n_ff_exp * n_expert_shared}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<llm_graph_context> llama_model_hy_v4::build_arch_graph(const llm_graph_params & params) const {
|
||||
return std::make_unique<graph>(*this, params);
|
||||
}
|
||||
|
||||
// reduce hc streams x[:,i,:] weighted by w[i,:] -> [n_embd, n_tokens]
|
||||
// reference runs this in fp32 (inside the float() / autocast(fp32) context)
|
||||
static ggml_tensor * hy_v4_hc_reduce(ggml_context * ctx0, ggml_tensor * x, ggml_tensor * w, int64_t hc, int64_t n_embd, int64_t nt, ggml_type out_type) {
|
||||
ggml_tensor * x_f32 = ggml_cast(ctx0, x, GGML_TYPE_F32);
|
||||
ggml_tensor * result = nullptr;
|
||||
for (int64_t ih = 0; ih < hc; ++ih) {
|
||||
ggml_tensor * xh = ggml_view_2d(ctx0, x_f32, n_embd, nt, x_f32->nb[2], ih * x_f32->nb[1]);
|
||||
ggml_tensor * wh = ggml_view_2d(ctx0, w, 1, nt, w->nb[1], ih * w->nb[0]);
|
||||
ggml_tensor * cur = ggml_mul(ctx0, xh, wh);
|
||||
result = result ? ggml_add(ctx0, result, cur) : cur;
|
||||
}
|
||||
return ggml_cast(ctx0, result, out_type);
|
||||
}
|
||||
|
||||
ggml_tensor * llama_model_hy_v4::graph::build_hc_pre(
|
||||
ggml_tensor * x,
|
||||
ggml_tensor * hc_fn,
|
||||
ggml_tensor * hc_scale,
|
||||
ggml_tensor * hc_base,
|
||||
ggml_tensor ** post,
|
||||
int il) const {
|
||||
const int64_t hc = hparams.dsv4_hc_mult;
|
||||
const int64_t nt = x->ne[2];
|
||||
GGML_ASSERT(x->ne[0] == n_embd && x->ne[1] == hc);
|
||||
|
||||
ggml_tensor * flat = ggml_reshape_2d(ctx0, x, hc * n_embd, nt);
|
||||
ggml_tensor * flat_norm = ggml_rms_norm(ctx0, flat, hparams.f_norm_rms_eps);
|
||||
ggml_tensor * mixes = ggml_mul_mat(ctx0, hc_fn, flat_norm); // [2*hc, nt]
|
||||
cb(mixes, "hc_mixes", il);
|
||||
|
||||
ggml_tensor * scale_pre = hy_v4_view_1d(ctx0, hc_scale, 1, 0);
|
||||
ggml_tensor * scale_post = hy_v4_view_1d(ctx0, hc_scale, 1, 1);
|
||||
ggml_tensor * base_pre = hy_v4_view_1d(ctx0, hc_base, hc, 0);
|
||||
ggml_tensor * base_post = hy_v4_view_1d(ctx0, hc_base, hc, hc);
|
||||
|
||||
// pre = sigmoid(mixes[:hc]*scale_pre + base_pre) + eps
|
||||
ggml_tensor * pre = hy_v4_view_2d(ctx0, mixes, hc, nt, 0);
|
||||
pre = ggml_mul(ctx0, pre, scale_pre);
|
||||
pre = ggml_add(ctx0, pre, base_pre);
|
||||
pre = ggml_sigmoid(ctx0, pre);
|
||||
pre = ggml_scale_bias(ctx0, pre, 1.0f, hparams.dsv4_hc_eps);
|
||||
cb(pre, "hc_pre", il);
|
||||
|
||||
// post = magnitude*sigmoid(mixes[hc:2hc]*scale_post + base_post) + eps
|
||||
ggml_tensor * po = hy_v4_view_2d(ctx0, mixes, hc, nt, hc);
|
||||
po = ggml_mul(ctx0, po, scale_post);
|
||||
po = ggml_add(ctx0, po, base_post);
|
||||
po = ggml_sigmoid(ctx0, po);
|
||||
po = ggml_scale(ctx0, po, hparams.hc_magnitude);
|
||||
po = ggml_scale_bias(ctx0, po, 1.0f, hparams.dsv4_hc_eps);
|
||||
*post = po;
|
||||
cb(po, "hc_post_gate", il);
|
||||
|
||||
return hy_v4_hc_reduce(ctx0, x, pre, hc, n_embd, nt, x->type);
|
||||
}
|
||||
|
||||
ggml_tensor * llama_model_hy_v4::graph::build_hc_post(
|
||||
ggml_tensor * x,
|
||||
ggml_tensor * residual,
|
||||
ggml_tensor * post,
|
||||
int il) const {
|
||||
GGML_UNUSED(il);
|
||||
const int64_t hc = hparams.dsv4_hc_mult;
|
||||
const int64_t nt = x->ne[1];
|
||||
GGML_ASSERT(x->ne[0] == n_embd);
|
||||
GGML_ASSERT(residual->ne[1] == hc);
|
||||
|
||||
// reference HC post runs entirely in fp32 to avoid bf16 rounding accumulation
|
||||
// across 78 layers: post.float() * x.float() + residual.float() -> .to(dtype)
|
||||
ggml_tensor * x_f32 = ggml_cast(ctx0, x, GGML_TYPE_F32);
|
||||
ggml_tensor * post_f32 = ggml_cast(ctx0, post, GGML_TYPE_F32);
|
||||
ggml_tensor * res_f32 = ggml_cast(ctx0, residual, GGML_TYPE_F32);
|
||||
|
||||
ggml_tensor * out = nullptr;
|
||||
for (int64_t i = 0; i < hc; ++i) {
|
||||
ggml_tensor * res_i = ggml_view_2d(ctx0, res_f32, n_embd, nt, res_f32->nb[2], i * res_f32->nb[1]);
|
||||
ggml_tensor * post_i = ggml_view_2d(ctx0, post_f32, 1, nt, post_f32->nb[1], i * post_f32->nb[0]);
|
||||
ggml_tensor * cur = ggml_add(ctx0, res_i, ggml_mul(ctx0, x_f32, post_i));
|
||||
cur = ggml_reshape_3d(ctx0, cur, n_embd, 1, nt);
|
||||
out = out ? ggml_concat(ctx0, out, cur, 1) : cur;
|
||||
}
|
||||
|
||||
// cast back to the original type (bf16)
|
||||
out = ggml_cast(ctx0, out, residual->type);
|
||||
return out; // [n_embd, hc, nt]
|
||||
}
|
||||
|
||||
ggml_tensor * llama_model_hy_v4::graph::build_hc_head(
|
||||
ggml_tensor * x,
|
||||
ggml_tensor * hc_fn,
|
||||
ggml_tensor * hc_scale,
|
||||
ggml_tensor * hc_base) const {
|
||||
const int64_t hc = hparams.dsv4_hc_mult;
|
||||
const int64_t nt = x->ne[2];
|
||||
|
||||
ggml_tensor * flat = ggml_reshape_2d(ctx0, x, hc * n_embd, nt);
|
||||
ggml_tensor * flat_norm = ggml_rms_norm(ctx0, flat, hparams.f_norm_rms_eps);
|
||||
ggml_tensor * mixes = ggml_mul_mat(ctx0, hc_fn, flat_norm); // [hc, nt]
|
||||
cb(mixes, "hc_head_mixes", -1);
|
||||
|
||||
ggml_tensor * pre = ggml_mul(ctx0, mixes, hc_scale);
|
||||
pre = ggml_add(ctx0, pre, hc_base);
|
||||
pre = ggml_sigmoid(ctx0, pre);
|
||||
pre = ggml_scale_bias(ctx0, pre, 1.0f, hparams.dsv4_hc_eps);
|
||||
cb(pre, "hc_head_pre", -1);
|
||||
|
||||
return hy_v4_hc_reduce(ctx0, x, pre, hc, n_embd, nt, x->type);
|
||||
}
|
||||
|
||||
ggml_tensor * llama_model_hy_v4::graph::build_attention(
|
||||
const llama_model & model,
|
||||
llm_graph_input_attn_k * inp_attn,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * inp_pos,
|
||||
float kq_scale,
|
||||
int il) const {
|
||||
const auto & layer = model.layers[il];
|
||||
|
||||
const int64_t n_embd_head_k = hparams.n_embd_head_k_mla();
|
||||
const int64_t n_embd_head_qk_rope = hparams.n_rot();
|
||||
const int64_t n_embd_head_qk_nope = n_embd_head_k - n_embd_head_qk_rope;
|
||||
const uint32_t kv_lora_rank = hparams.n_lora_kv;
|
||||
|
||||
ggml_tensor * q = ggml_mul_mat(ctx0, layer.wq_a, cur);
|
||||
q = build_norm(q, layer.attn_q_a_norm, nullptr, LLM_NORM_RMS, il);
|
||||
q = ggml_mul_mat(ctx0, layer.wq_b, q);
|
||||
|
||||
ggml_tensor * q_nope = ggml_view_3d(ctx0, q, n_embd_head_qk_nope, n_head, n_tokens,
|
||||
ggml_row_size(q->type, n_embd_head_k), ggml_row_size(q->type, n_embd_head_k) * n_head, 0);
|
||||
ggml_tensor * q_pe = ggml_view_3d(ctx0, q, n_embd_head_qk_rope, n_head, n_tokens,
|
||||
ggml_row_size(q->type, n_embd_head_k), ggml_row_size(q->type, n_embd_head_k) * n_head,
|
||||
ggml_row_size(q->type, n_embd_head_qk_nope));
|
||||
|
||||
ggml_tensor * kv_cmpr_pe = ggml_mul_mat(ctx0, layer.wkv_a_mqa, cur);
|
||||
ggml_tensor * kv_cmpr = ggml_view_2d(ctx0, kv_cmpr_pe, kv_lora_rank, n_tokens,
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank + n_embd_head_qk_rope), 0);
|
||||
ggml_tensor * k_pe = ggml_view_3d(ctx0, kv_cmpr_pe, n_embd_head_qk_rope, 1, n_tokens,
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank + n_embd_head_qk_rope),
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank + n_embd_head_qk_rope),
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank));
|
||||
|
||||
q_pe = ggml_rope_ext(ctx0, q_pe, inp_pos, nullptr, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
|
||||
ext_factor, attn_factor, beta_fast, beta_slow);
|
||||
cb(q_pe, "q_pe", il);
|
||||
k_pe = ggml_rope_ext(ctx0, k_pe, inp_pos, nullptr, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
|
||||
ext_factor, attn_factor, beta_fast, beta_slow);
|
||||
cb(k_pe, "k_pe", il);
|
||||
|
||||
kv_cmpr = build_norm(kv_cmpr, layer.attn_kv_a_norm, nullptr, LLM_NORM_RMS, il);
|
||||
cb(kv_cmpr, "kv_cmpr", il);
|
||||
|
||||
// MLA absorption: q_nope @ wk_b -> compressed space
|
||||
q_nope = ggml_permute(ctx0, q_nope, 0, 2, 1, 3);
|
||||
ggml_tensor * q_nope_absorbed = ggml_mul_mat(ctx0, layer.wk_b, q_nope);
|
||||
q_nope_absorbed = ggml_permute(ctx0, q_nope_absorbed, 0, 2, 1, 3);
|
||||
|
||||
// note: rope must go first for in-place context shifting in build_rope_shift()
|
||||
ggml_tensor * Qcur = ggml_concat(ctx0, q_nope_absorbed, q_pe, 0);
|
||||
|
||||
kv_cmpr = ggml_reshape_3d(ctx0, kv_cmpr, kv_lora_rank, 1, n_tokens);
|
||||
ggml_tensor * Kcur = ggml_concat(ctx0, kv_cmpr, k_pe, 0);
|
||||
ggml_tensor * Vcur = kv_cmpr;
|
||||
|
||||
// MLA-as-MQA; wo applied manually below so the gated-MLA gate can sit before o_proj
|
||||
ggml_tensor * attn = build_attn(inp_attn,
|
||||
nullptr, nullptr, nullptr,
|
||||
Qcur, Kcur, Vcur, nullptr, layer.attn_sinks, layer.wv_b, kq_scale, il);
|
||||
cb(attn, "attn_kqv", il); // [n_head * n_embd_head_v, n_tokens]
|
||||
|
||||
// gated MLA: elementwise sigmoid gate on the decompressed attention output
|
||||
ggml_tensor * gate = ggml_mul_mat(ctx0, layer.wqkv_gate, cur);
|
||||
gate = ggml_sigmoid(ctx0, gate);
|
||||
attn = ggml_mul(ctx0, attn, gate);
|
||||
cb(attn, "attn_gated", il);
|
||||
|
||||
ggml_tensor * out = build_lora_mm(layer.wo, attn);
|
||||
cb(out, "attn_out", il);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
ggml_tensor * llama_model_hy_v4::graph::build_indexer_top_k(
|
||||
const llama_model & model,
|
||||
llm_graph_input_attn_k_dsa * inp_attn_dsa,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * qr,
|
||||
ggml_tensor * inp_pos,
|
||||
int il) const {
|
||||
const auto & layer = model.layers[il];
|
||||
|
||||
const int64_t n_indexer_head = hparams.indexer_n_head;
|
||||
const int64_t n_embd_indexer = hparams.indexer_head_size;
|
||||
const int64_t n_embd_indexer_rope = hparams.n_rot();
|
||||
const int64_t n_embd_indexer_nope = n_embd_indexer - n_embd_indexer_rope;
|
||||
|
||||
// nope rows come first, so rope only the last n_embd_indexer_rope rows, same as the MLA path
|
||||
ggml_tensor * iq = ggml_mul_mat(ctx0, layer.indexer_attn_q_b, qr);
|
||||
|
||||
iq = ggml_reshape_3d(ctx0, iq, n_embd_indexer, n_indexer_head, n_tokens);
|
||||
|
||||
iq = ggml_rope_ext(ctx0, iq, inp_pos, nullptr, n_rot, rope_type, n_ctx_orig, freq_base,
|
||||
freq_scale, ext_factor, attn_factor, beta_fast, beta_slow);
|
||||
iq = ggml_rope_set_offset(iq, n_embd_indexer_nope);
|
||||
cb(iq, "indexer_q", il);
|
||||
|
||||
ggml_tensor * ik = ggml_mul_mat(ctx0, layer.indexer_attn_k, cur);
|
||||
|
||||
ik = build_norm(ik, layer.indexer_k_norm, layer.indexer_k_norm_b, LLM_NORM, il);
|
||||
|
||||
ik = ggml_reshape_3d(ctx0, ik, n_embd_indexer, 1, n_tokens);
|
||||
|
||||
ik = ggml_rope_ext(ctx0, ik, inp_pos, nullptr, n_rot, rope_type, n_ctx_orig, freq_base,
|
||||
freq_scale, ext_factor, attn_factor, beta_fast, beta_slow);
|
||||
ik = ggml_rope_set_offset(ik, n_embd_indexer_nope);
|
||||
cb(ik, "indexer_k", il);
|
||||
|
||||
// the reference applies a Hadamard rotation here, but it only helps its FP8 kernels.
|
||||
// it is orthogonal, so it does not change q.k and we can skip it.
|
||||
|
||||
const auto * mctx_lid = inp_attn_dsa->mctx->get_lid();
|
||||
const auto & k_idxs_lid = inp_attn_dsa->get_k_idxs_lid();
|
||||
ggml_build_forward_expand(gf, mctx_lid->cpy_k(ctx0, ik, k_idxs_lid, il));
|
||||
|
||||
ggml_tensor * iw = ggml_mul_mat(ctx0, layer.indexer_proj, cur);
|
||||
|
||||
ik = mctx_lid->get_k(ctx0, il);
|
||||
|
||||
const auto n_stream = ik->ne[3];
|
||||
iq = ggml_view_4d(ctx0, iq, iq->ne[0], iq->ne[1], iq->ne[2]/n_stream, n_stream,
|
||||
iq->nb[1], iq->nb[2], iq->nb[3]/n_stream, 0);
|
||||
iw = ggml_view_4d(ctx0, iw, iw->ne[0], iw->ne[1]/n_stream, iw->ne[2], n_stream,
|
||||
iw->nb[1], iw->nb[2]/n_stream, iw->nb[3]/n_stream, 0);
|
||||
|
||||
// fold both reference scale factors into the weights before the big score tensor
|
||||
iw = ggml_scale(ctx0, iw, 1.0f / sqrtf(float(n_embd_indexer * n_indexer_head)));
|
||||
|
||||
ggml_tensor * score = nullptr;
|
||||
if (cparams.fused_lid) {
|
||||
score = ggml_lightning_indexer(ctx0, iq, ik, iw, inp_attn_dsa->get_kq_mask_lid());
|
||||
cb(score, "indexer_score", il);
|
||||
res->add_fused_node({LLM_FUSED_OP_LIGHTNING_INDEXER, score, il});
|
||||
} else {
|
||||
iq = ggml_permute(ctx0, iq, 0, 2, 1, 3);
|
||||
ik = ggml_permute(ctx0, ik, 0, 2, 1, 3);
|
||||
|
||||
score = ggml_mul_mat(ctx0, ik, iq);
|
||||
score = ggml_cont(ctx0, ggml_permute(ctx0, score, 2, 1, 0, 3));
|
||||
score = ggml_relu(ctx0, score);
|
||||
score = ggml_mul(ctx0, score, iw);
|
||||
score = ggml_sum_rows(ctx0, score);
|
||||
score = ggml_cont(ctx0, ggml_permute(ctx0, score, 2, 1, 0, 3));
|
||||
score = ggml_add(ctx0, score, inp_attn_dsa->get_kq_mask_lid());
|
||||
cb(score, "indexer_score", il);
|
||||
}
|
||||
|
||||
const uint32_t n_top_k = score->ne[0] < (int64_t) hparams.indexer_top_k ? score->ne[0] : hparams.indexer_top_k;
|
||||
|
||||
return ggml_cont(ctx0, ggml_top_k(ctx0, score, n_top_k));
|
||||
}
|
||||
|
||||
ggml_tensor * llama_model_hy_v4::graph::build_attention_dsa(
|
||||
const llama_model & model,
|
||||
llm_graph_input_attn_k_dsa * inp_attn_dsa,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * inp_pos,
|
||||
ggml_tensor ** last_top_k,
|
||||
float kq_scale,
|
||||
int il) const {
|
||||
const auto & layer = model.layers[il];
|
||||
|
||||
const int64_t n_embd_head_k = hparams.n_embd_head_k_mla();
|
||||
const int64_t n_embd_head_qk_rope = hparams.n_rot();
|
||||
const int64_t n_embd_head_qk_nope = n_embd_head_k - n_embd_head_qk_rope;
|
||||
const uint32_t kv_lora_rank = hparams.n_lora_kv;
|
||||
|
||||
ggml_tensor * qr = ggml_mul_mat(ctx0, layer.wq_a, cur);
|
||||
qr = build_norm(qr, layer.attn_q_a_norm, nullptr, LLM_NORM_RMS, il);
|
||||
|
||||
if (hparams.is_indexer_full(il)) {
|
||||
*last_top_k = build_indexer_top_k(model, inp_attn_dsa, cur, qr, inp_pos, il);
|
||||
cb(*last_top_k, "top_k", il);
|
||||
}
|
||||
GGML_ASSERT(*last_top_k != nullptr);
|
||||
|
||||
ggml_tensor * q = ggml_mul_mat(ctx0, layer.wq_b, qr);
|
||||
|
||||
ggml_tensor * q_nope = ggml_view_3d(ctx0, q, n_embd_head_qk_nope, n_head, n_tokens,
|
||||
ggml_row_size(q->type, n_embd_head_k), ggml_row_size(q->type, n_embd_head_k) * n_head, 0);
|
||||
ggml_tensor * q_pe = ggml_view_3d(ctx0, q, n_embd_head_qk_rope, n_head, n_tokens,
|
||||
ggml_row_size(q->type, n_embd_head_k), ggml_row_size(q->type, n_embd_head_k) * n_head,
|
||||
ggml_row_size(q->type, n_embd_head_qk_nope));
|
||||
|
||||
ggml_tensor * kv_cmpr_pe = ggml_mul_mat(ctx0, layer.wkv_a_mqa, cur);
|
||||
ggml_tensor * kv_cmpr = ggml_view_2d(ctx0, kv_cmpr_pe, kv_lora_rank, n_tokens,
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank + n_embd_head_qk_rope), 0);
|
||||
ggml_tensor * k_pe = ggml_view_3d(ctx0, kv_cmpr_pe, n_embd_head_qk_rope, 1, n_tokens,
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank + n_embd_head_qk_rope),
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank + n_embd_head_qk_rope),
|
||||
ggml_row_size(kv_cmpr_pe->type, kv_lora_rank));
|
||||
|
||||
q_pe = ggml_rope_ext(ctx0, q_pe, inp_pos, nullptr, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
|
||||
ext_factor, attn_factor, beta_fast, beta_slow);
|
||||
cb(q_pe, "q_pe", il);
|
||||
k_pe = ggml_rope_ext(ctx0, k_pe, inp_pos, nullptr, n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
|
||||
ext_factor, attn_factor, beta_fast, beta_slow);
|
||||
cb(k_pe, "k_pe", il);
|
||||
|
||||
kv_cmpr = build_norm(kv_cmpr, layer.attn_kv_a_norm, nullptr, LLM_NORM_RMS, il);
|
||||
cb(kv_cmpr, "kv_cmpr", il);
|
||||
|
||||
q_nope = ggml_permute(ctx0, q_nope, 0, 2, 1, 3);
|
||||
ggml_tensor * q_nope_absorbed = ggml_mul_mat(ctx0, layer.wk_b, q_nope);
|
||||
q_nope_absorbed = ggml_permute(ctx0, q_nope_absorbed, 0, 2, 1, 3);
|
||||
|
||||
ggml_tensor * Qcur = ggml_concat(ctx0, q_nope_absorbed, q_pe, 0);
|
||||
|
||||
kv_cmpr = ggml_reshape_3d(ctx0, kv_cmpr, kv_lora_rank, 1, n_tokens);
|
||||
ggml_tensor * Kcur = ggml_concat(ctx0, kv_cmpr, k_pe, 0);
|
||||
ggml_tensor * Vcur = kv_cmpr;
|
||||
|
||||
ggml_tensor * attn = build_attn(inp_attn_dsa,
|
||||
nullptr, nullptr, nullptr,
|
||||
Qcur, Kcur, Vcur, nullptr, layer.attn_sinks, layer.wv_b, *last_top_k, kq_scale, il);
|
||||
cb(attn, "attn_kqv", il);
|
||||
|
||||
ggml_tensor * gate = ggml_mul_mat(ctx0, layer.wqkv_gate, cur);
|
||||
gate = ggml_sigmoid(ctx0, gate);
|
||||
attn = ggml_mul(ctx0, attn, gate);
|
||||
cb(attn, "attn_gated", il);
|
||||
|
||||
ggml_tensor * out = build_lora_mm(layer.wo, attn);
|
||||
cb(out, "attn_out", il);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
llama_model_hy_v4::graph::graph(const llama_model & model, const llm_graph_params & params) :
|
||||
llm_graph_context(params) {
|
||||
const int64_t hc = hparams.dsv4_hc_mult;
|
||||
const int64_t n_embd_head_k = hparams.n_embd_head_k_mla();
|
||||
const float kq_scale = 1.0f / sqrtf(float(n_embd_head_k));
|
||||
|
||||
ggml_tensor * cur;
|
||||
|
||||
const bool is_dsa = hparams.indexer_top_k > 0;
|
||||
|
||||
ggml_tensor * inp = build_inp_embd(model.tok_embd);
|
||||
ggml_tensor * inp_pos = build_inp_pos();
|
||||
llm_graph_input_attn_k * inp_attn = is_dsa ? nullptr : build_attn_inp_k();
|
||||
llm_graph_input_attn_k_dsa * inp_attn_dsa = is_dsa ? build_attn_inp_k_dsa() : nullptr;
|
||||
ggml_tensor * inp_out_ids = build_inp_out_ids();
|
||||
|
||||
// top-k of the last "full" indexer layer, reused by the following "shared" layers
|
||||
ggml_tensor * last_top_k = nullptr;
|
||||
|
||||
// expand the single embedding into hc parallel residual streams
|
||||
ggml_tensor * inpL = ggml_reshape_3d(ctx0, inp, n_embd, 1, n_tokens);
|
||||
inpL = ggml_repeat_4d(ctx0, inpL, n_embd, hc, n_tokens, 1);
|
||||
cb(inpL, "hc_init", -1);
|
||||
|
||||
for (int il = 0; il < n_layer; ++il) {
|
||||
ggml_tensor * residual = inpL;
|
||||
ggml_tensor * post = nullptr;
|
||||
|
||||
cur = build_hc_pre(inpL, model.layers[il].hc_attn_fn, model.layers[il].hc_attn_scale,
|
||||
model.layers[il].hc_attn_base, &post, il);
|
||||
cur = build_norm(cur, model.layers[il].attn_norm, nullptr, LLM_NORM_RMS, il);
|
||||
cb(cur, "attn_norm", il);
|
||||
|
||||
cur = is_dsa
|
||||
? build_attention_dsa(model, inp_attn_dsa, cur, inp_pos, &last_top_k, kq_scale, il)
|
||||
: build_attention(model, inp_attn, cur, inp_pos, kq_scale, il);
|
||||
|
||||
inpL = build_hc_post(cur, residual, post, il);
|
||||
cb(inpL, "hc_attn_out", il);
|
||||
|
||||
residual = inpL;
|
||||
cur = build_hc_pre(inpL, model.layers[il].hc_ffn_fn, model.layers[il].hc_ffn_scale,
|
||||
model.layers[il].hc_ffn_base, &post, il);
|
||||
cur = build_norm(cur, model.layers[il].ffn_norm, nullptr, LLM_NORM_RMS, il);
|
||||
cb(cur, "ffn_norm", il);
|
||||
|
||||
const auto & layer = model.layers[il];
|
||||
if ((uint32_t) il < hparams.n_layer_dense_lead) {
|
||||
cur = build_ffn(cur,
|
||||
layer.ffn_up, NULL, NULL,
|
||||
layer.ffn_gate, NULL, NULL,
|
||||
layer.ffn_down, NULL, NULL,
|
||||
NULL, LLM_FFN_SILU, LLM_FFN_PAR, il);
|
||||
cb(cur, "ffn_out", il);
|
||||
} else {
|
||||
ggml_tensor * moe_out = build_moe_ffn(cur,
|
||||
layer.ffn_gate_inp,
|
||||
layer.ffn_up_exps,
|
||||
layer.ffn_gate_exps,
|
||||
layer.ffn_down_exps,
|
||||
layer.ffn_exp_probs_b,
|
||||
n_expert, n_expert_used,
|
||||
LLM_FFN_SILU, hparams.expert_weights_norm,
|
||||
hparams.expert_weights_scale,
|
||||
(llama_expert_gating_func_type) hparams.expert_gating_func,
|
||||
il,
|
||||
nullptr,
|
||||
nullptr);
|
||||
cb(moe_out, "ffn_moe_out", il);
|
||||
|
||||
ggml_tensor * ffn_shexp = build_ffn(cur,
|
||||
layer.ffn_up_shexp, NULL, NULL,
|
||||
layer.ffn_gate_shexp, NULL, NULL,
|
||||
layer.ffn_down_shexp, NULL, NULL,
|
||||
NULL, LLM_FFN_SILU, LLM_FFN_PAR, il);
|
||||
cb(ffn_shexp, "ffn_shexp", il);
|
||||
|
||||
cur = ggml_add(ctx0, moe_out, ffn_shexp);
|
||||
cb(cur, "ffn_out", il);
|
||||
}
|
||||
|
||||
inpL = build_hc_post(cur, residual, post, il);
|
||||
cb(inpL, "l_out", il);
|
||||
}
|
||||
|
||||
// prune to the requested output rows once, after all HC streams are done
|
||||
if (inp_out_ids) {
|
||||
ggml_tensor * flat = ggml_reshape_2d(ctx0, inpL, n_embd * hc, n_tokens);
|
||||
flat = ggml_get_rows(ctx0, flat, inp_out_ids);
|
||||
inpL = ggml_reshape_3d(ctx0, flat, n_embd, hc, n_outputs);
|
||||
}
|
||||
|
||||
cur = build_hc_head(inpL, model.hc_head_fn, model.hc_head_scale, model.hc_head_base);
|
||||
cb(cur, "hc_head", -1);
|
||||
|
||||
cur = build_norm(cur, model.output_norm, nullptr, LLM_NORM_RMS, -1);
|
||||
cb(cur, "result_norm", -1);
|
||||
res->t_embd = cur;
|
||||
|
||||
cur = ggml_mul_mat(ctx0, model.output, cur);
|
||||
cb(cur, "result_output", -1);
|
||||
res->t_logits = cur;
|
||||
|
||||
ggml_build_forward_expand(gf, cur);
|
||||
}
|
||||
@@ -1981,6 +1981,69 @@ struct llama_model_hy_v3 : public llama_model_base {
|
||||
};
|
||||
|
||||
|
||||
struct llama_model_hy_v4 : public llama_model_base {
|
||||
llama_model_hy_v4(const struct llama_model_params & params) : llama_model_base(params) {}
|
||||
void load_arch_hparams(llama_model_loader & ml) override;
|
||||
void load_arch_tensors(llama_model_loader & ml) override;
|
||||
|
||||
struct graph : public llm_graph_context {
|
||||
graph(const llama_model & model, const llm_graph_params & params);
|
||||
|
||||
// iHC (independent Hyper-Connections): pre reduces the hc streams to one and returns the
|
||||
// per-stream post gates, post writes the sublayer output back into the streams, head
|
||||
// collapses the streams before the final norm.
|
||||
ggml_tensor * build_hc_pre(
|
||||
ggml_tensor * x,
|
||||
ggml_tensor * hc_fn,
|
||||
ggml_tensor * hc_scale,
|
||||
ggml_tensor * hc_base,
|
||||
ggml_tensor ** post,
|
||||
int il) const;
|
||||
|
||||
ggml_tensor * build_hc_post(
|
||||
ggml_tensor * x,
|
||||
ggml_tensor * residual,
|
||||
ggml_tensor * post,
|
||||
int il) const;
|
||||
|
||||
ggml_tensor * build_hc_head(
|
||||
ggml_tensor * x,
|
||||
ggml_tensor * hc_fn,
|
||||
ggml_tensor * hc_scale,
|
||||
ggml_tensor * hc_base) const;
|
||||
|
||||
ggml_tensor * build_attention(
|
||||
const llama_model & model,
|
||||
llm_graph_input_attn_k * inp_attn,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * inp_pos,
|
||||
float kq_scale,
|
||||
int il) const;
|
||||
|
||||
// DSA lightning indexer: top-k KV positions for this layer. Only "full" layers compute
|
||||
// it, "shared" layers reuse the last preceding full layer result through last_top_k.
|
||||
ggml_tensor * build_indexer_top_k(
|
||||
const llama_model & model,
|
||||
llm_graph_input_attn_k_dsa * inp_attn_dsa,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * qr,
|
||||
ggml_tensor * inp_pos,
|
||||
int il) const;
|
||||
|
||||
ggml_tensor * build_attention_dsa(
|
||||
const llama_model & model,
|
||||
llm_graph_input_attn_k_dsa * inp_attn_dsa,
|
||||
ggml_tensor * cur,
|
||||
ggml_tensor * inp_pos,
|
||||
ggml_tensor ** last_top_k,
|
||||
float kq_scale,
|
||||
int il) const;
|
||||
};
|
||||
|
||||
std::unique_ptr<llm_graph_context> build_arch_graph(const llm_graph_params & params) const override;
|
||||
};
|
||||
|
||||
|
||||
struct llama_model_hunyuan_vl : public llama_model_base {
|
||||
llama_model_hunyuan_vl(const struct llama_model_params & params) : llama_model_base(params) {}
|
||||
void load_arch_hparams(llama_model_loader & ml) override;
|
||||
|
||||
+115
-14
@@ -4742,6 +4742,51 @@ struct test_mul_mat : public test_case {
|
||||
}
|
||||
};
|
||||
|
||||
#define P 1.0f
|
||||
#define N -1.0f
|
||||
|
||||
// constant Hadamard matrix via Paley I construction
|
||||
static constexpr float H12[12][12] = {
|
||||
{ P, P, P, P, P, P, P, P, P, P, P, P },
|
||||
{ P, N, P, N, P, P, P, N, N, N, P, N },
|
||||
{ P, N, N, P, N, P, P, P, N, N, N, P },
|
||||
{ P, P, N, N, P, N, P, P, P, N, N, N },
|
||||
{ P, N, P, N, N, P, N, P, P, P, N, N },
|
||||
{ P, N, N, P, N, N, P, N, P, P, P, N },
|
||||
{ P, N, N, N, P, N, N, P, N, P, P, P },
|
||||
{ P, P, N, N, N, P, N, N, P, N, P, P },
|
||||
{ P, P, P, N, N, N, P, N, N, P, N, P },
|
||||
{ P, P, P, P, N, N, N, P, N, N, P, N },
|
||||
{ P, N, P, P, P, N, N, N, P, N, N, P },
|
||||
{ P, P, N, P, P, P, N, N, N, P, N, N }
|
||||
};
|
||||
|
||||
static constexpr float H20[20][20] = {
|
||||
{ P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P },
|
||||
{ P, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N },
|
||||
{ P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P },
|
||||
{ P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P },
|
||||
{ P, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N },
|
||||
{ P, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N, N },
|
||||
{ P, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N, N },
|
||||
{ P, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P, N },
|
||||
{ P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N, P },
|
||||
{ P, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P, N },
|
||||
{ P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N, P },
|
||||
{ P, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P, N },
|
||||
{ P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P, P },
|
||||
{ P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P, P },
|
||||
{ P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P, P },
|
||||
{ P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N, P },
|
||||
{ P, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N, N },
|
||||
{ P, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P, N },
|
||||
{ P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N, P },
|
||||
{ P, P, N, N, P, P, P, P, N, P, N, P, N, N, N, N, P, P, N, N }
|
||||
};
|
||||
|
||||
#undef P
|
||||
#undef N
|
||||
|
||||
// GGML_HINT_SRC0_IS_HADAMARD
|
||||
struct test_mul_mat_hadamard : public test_mul_mat {
|
||||
test_mul_mat_hadamard(ggml_type type_a = GGML_TYPE_F32, ggml_type type_b = GGML_TYPE_F32,
|
||||
@@ -4766,20 +4811,58 @@ struct test_mul_mat_hadamard : public test_mul_mat {
|
||||
void initialize_tensors(ggml_context * ctx) override {
|
||||
for (ggml_tensor * t = ggml_get_first_tensor(ctx); t != NULL; t = ggml_get_next_tensor(ctx, t)) {
|
||||
if (strcmp(t->name, "a") == 0) {
|
||||
const int64_t n_cols = t->ne[0];
|
||||
const int64_t n_rows = ggml_nrows(t);
|
||||
const int64_t n_cols = t->ne[0];
|
||||
const int64_t n_rows = ggml_nrows(t);
|
||||
std::vector<float> data(n_cols * n_rows);
|
||||
float scale = 1.0f / sqrtf((float)n_cols);
|
||||
for (int64_t r = 0; r < n_rows; r++) {
|
||||
float * row_data = data.data() + r * n_cols;
|
||||
for (int64_t i = 0; i < n_cols; i++) {
|
||||
int pop = 0;
|
||||
int64_t val = r & i;
|
||||
while (val) {
|
||||
pop += (val & 1);
|
||||
val >>= 1;
|
||||
float scale = 1.0f / sqrtf((float) n_cols);
|
||||
|
||||
auto is_pow2 = [](const int64_t a) {
|
||||
return (a > 0) && ((a & (a - 1)) == 0);
|
||||
};
|
||||
#ifdef GGML_USE_SYCL
|
||||
const bool is_kronecker =
|
||||
((n_cols % 12 == 0) && is_pow2(n_cols / 12)) || ((n_cols % 20 == 0) && is_pow2(n_cols / 20));
|
||||
#else
|
||||
const bool is_kronecker = false;
|
||||
#endif
|
||||
if (is_kronecker) {
|
||||
const int64_t B = (n_cols % 12 == 0 && is_pow2(n_cols / 12)) ? 12 : 20;
|
||||
for (int64_t r = 0; r < n_rows; r++) {
|
||||
float * row_data = data.data() + r * n_cols;
|
||||
const int64_t r_mod = r % n_cols;
|
||||
const int64_t r_b = r_mod / B;
|
||||
const int64_t r_m = r_mod % B;
|
||||
|
||||
for (int64_t i = 0; i < n_cols; i++) {
|
||||
const int64_t c_b = i / B;
|
||||
const int64_t c_m = i % B;
|
||||
|
||||
int pop = 0;
|
||||
int64_t val = r_b & c_b;
|
||||
while (val) {
|
||||
pop += (val & 1);
|
||||
val >>= 1;
|
||||
}
|
||||
const float sign_m = (pop % 2 == 0) ? 1.0f : -1.0f;
|
||||
const float sign_b = (B == 12) ? H12[c_m][r_m] : H20[c_m][r_m];
|
||||
|
||||
row_data[i] = scale * sign_b * sign_m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (is_pow2(n_cols)) {
|
||||
for (int64_t r = 0; r < n_rows; r++) {
|
||||
float * row_data = data.data() + r * n_cols;
|
||||
for (int64_t i = 0; i < n_cols; i++) {
|
||||
int pop_cnt = 0;
|
||||
int64_t val = r & i;
|
||||
while (val) {
|
||||
pop_cnt += (val & 1);
|
||||
val >>= 1;
|
||||
}
|
||||
row_data[i] = (pop_cnt % 2 == 0) ? scale : -scale;
|
||||
}
|
||||
row_data[i] = (pop % 2 == 0) ? scale : -scale;
|
||||
}
|
||||
}
|
||||
ggml_backend_tensor_set(t, data.data(), 0, data.size() * sizeof(float));
|
||||
@@ -9469,7 +9552,16 @@ static std::vector<std::unique_ptr<test_case>> make_test_cases_eval() {
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 256, 512, 256)); // many rows
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 32, 1, 32)); // too small (N<64)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 1024, 1, 1024)); // too big (N>512)
|
||||
|
||||
#ifdef GGML_USE_SYCL
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 384, 1, 384)); // m=12 (N=384)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 384, 32, 384)); // m=12 (batch)
|
||||
test_cases.emplace_back(
|
||||
new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 384, 4, 384, { 2, 3 })); // m=12 (multi-dim)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 768, 1, 768)); // m=12 (N=768)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 640, 1, 640)); // m=20 (N=640)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 640, 32, 640)); // m=20 (batch)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 1280, 1, 1280)); // m=20 (N=1280)
|
||||
#endif
|
||||
#if 0
|
||||
// > 4GB A matrix. Too slow to be enabled by default.
|
||||
test_cases.emplace_back(new test_mul_mat(GGML_TYPE_F16, GGML_TYPE_F16, 900000, 3, 2592, {1, 1}, {1, 1}));
|
||||
@@ -10739,7 +10831,16 @@ static std::vector<std::unique_ptr<test_case>> make_test_cases_perf() {
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 128, 2048, 128));
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 256, 2048, 256));
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 512, 2048, 512));
|
||||
|
||||
#ifdef GGML_USE_SYCL
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 384, 1, 384)); // m=12 (N=384)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 384, 32, 384)); // m=12 (batch)
|
||||
test_cases.emplace_back(
|
||||
new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 384, 4, 384, { 2, 3 })); // m=12 (multi-dim)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 768, 1, 768)); // m=12 (N=768)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 640, 1, 640)); // m=20 (N=640)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 640, 32, 640)); // m=20 (batch)
|
||||
test_cases.emplace_back(new test_mul_mat_hadamard(GGML_TYPE_F32, GGML_TYPE_F32, 1280, 1, 1280)); // m=20 (N=1280)
|
||||
#endif
|
||||
test_cases.emplace_back(new test_solve_tri(GGML_TYPE_F32, { 64, 64, 4, 4 }, { 32, 64, 4, 4 }));
|
||||
test_cases.emplace_back(new test_solve_tri(GGML_TYPE_F32, { 128, 128, 4, 2 }, { 32, 128, 4, 2 }));
|
||||
// qwen3next with CHUNK_SIZE 64
|
||||
|
||||
@@ -118,7 +118,8 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
|
||||
|| arch == LLM_ARCH_KIMI_LINEAR
|
||||
|| arch == LLM_ARCH_BAILINGMOE3
|
||||
|| arch == LLM_ARCH_KIMI_K3
|
||||
|| arch == LLM_ARCH_MISTRAL4) {
|
||||
|| arch == LLM_ARCH_MISTRAL4
|
||||
|| arch == LLM_ARCH_HY_V4) {
|
||||
n_embd = 128;
|
||||
n_head = 1;
|
||||
n_ff = 192;
|
||||
@@ -191,7 +192,8 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
|
||||
|| arch == LLM_ARCH_KIMI_LINEAR
|
||||
|| arch == LLM_ARCH_BAILINGMOE3
|
||||
|| arch == LLM_ARCH_KIMI_K3
|
||||
|| arch == LLM_ARCH_MISTRAL4) {
|
||||
|| arch == LLM_ARCH_MISTRAL4
|
||||
|| arch == LLM_ARCH_HY_V4) {
|
||||
ms.add_kv(LLM_KV_ATTENTION_KEY_LENGTH, uint32_t(576));
|
||||
ms.add_kv(LLM_KV_ATTENTION_VALUE_LENGTH, uint32_t(512));
|
||||
ms.add_kv(LLM_KV_ROPE_DIMENSION_COUNT, uint32_t(64));
|
||||
@@ -291,6 +293,22 @@ static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {
|
||||
ms.add_kv(LLM_KV_ATTENTION_INDEXER_LOCAL_BLOCKS, uint32_t(1));
|
||||
ms.add_kv(LLM_KV_ROPE_DIMENSION_SECTIONS, std::vector<uint32_t>({n_embd_head/4, n_embd_head/4, n_embd_head/4, n_embd_head/4}));
|
||||
|
||||
if (arch == LLM_ARCH_HY_V4) {
|
||||
ms.add_kv(LLM_KV_HYPER_CONNECTION_COUNT, uint32_t(4));
|
||||
ms.add_kv(LLM_KV_HYPER_CONNECTION_EPSILON, 1.0e-6f);
|
||||
ms.add_kv(LLM_KV_HYPER_CONNECTION_MAGNITUDE, 2.0f);
|
||||
ms.add_kv(LLM_KV_SWIGLU_CLAMP_EXP, 10.0f);
|
||||
ms.add_kv(LLM_KV_EXPERT_WEIGHTS_SCALE, 1.0f);
|
||||
ms.add_kv(LLM_KV_EXPERT_WEIGHTS_NORM, true);
|
||||
// layer 0 must own an indexer, the odd layers share it
|
||||
std::vector<uint32_t> indexer_types;
|
||||
indexer_types.reserve(n_layer);
|
||||
for (uint32_t il = 0; il < n_layer; il++) {
|
||||
indexer_types.push_back(il % 2 ? 0 : 1);
|
||||
}
|
||||
ms.add_kv(LLM_KV_ATTENTION_INDEXER_TYPES, indexer_types);
|
||||
}
|
||||
|
||||
if (arch == LLM_ARCH_DEEPSEEK4) {
|
||||
ms.add_kv(LLM_KV_ATTENTION_OUTPUT_GROUP_COUNT, uint32_t(8));
|
||||
ms.add_kv(LLM_KV_ATTENTION_OUTPUT_LORA_RANK, uint32_t(32));
|
||||
@@ -468,6 +486,7 @@ static bool moe_mandatory(const llm_arch arch) {
|
||||
case LLM_ARCH_ERNIE4_5_MOE:
|
||||
case LLM_ARCH_HUNYUAN_MOE:
|
||||
case LLM_ARCH_HY_V3:
|
||||
case LLM_ARCH_HY_V4:
|
||||
case LLM_ARCH_OPENAI_MOE:
|
||||
case LLM_ARCH_LFM2MOE:
|
||||
case LLM_ARCH_SMALLTHINKER:
|
||||
|
||||
+1
-2
@@ -1636,8 +1636,7 @@ struct clip_model_loader {
|
||||
hparams.patch_size = hparams.patch_size * hparams.n_merge;
|
||||
hparams.n_merge = 1;
|
||||
}
|
||||
// @ngxson : the model performs quite poor with small images, we need to bump minimum image tokens to 40 to avoid that
|
||||
hparams.set_limit_image_tokens(40, 280);
|
||||
hparams.set_limit_image_tokens(70, 1120);
|
||||
hparams.set_warmup_n_tokens(256); // avoid OOM on warmup
|
||||
} break;
|
||||
|
||||
|
||||
+3
-1
@@ -2173,9 +2173,11 @@ bool mtmd_decode_use_non_causal(const mtmd_context * ctx, const mtmd_input_chunk
|
||||
proj_type = ctx->proj_type_a();
|
||||
}
|
||||
switch (proj_type) {
|
||||
case PROJECTOR_TYPE_GEMMA3:
|
||||
case PROJECTOR_TYPE_GEMMA4V:
|
||||
// E2B (n_embd = 1536) and E4B (n_embd = 2560) always use causal
|
||||
return ctx->n_embd_text != 1536 && ctx->n_embd_text != 2560;
|
||||
case PROJECTOR_TYPE_GEMMA4UV:
|
||||
case PROJECTOR_TYPE_GEMMA3:
|
||||
case PROJECTOR_TYPE_DEEPSEEK4V:
|
||||
return true;
|
||||
default:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "npm run build-pwa-assets && vite build",
|
||||
"build-pwa-assets": "npx @vite-pwa/assets-generator --root . --config pwa-assets.config.ts && npx @vite-pwa/assets-generator --root . --config pwa-assets-dark.config.ts && node scripts/make-icons-circular.js",
|
||||
"build-pwa-assets": "pwa-assets-generator --root . --config pwa-assets.config.ts && pwa-assets-generator --root . --config pwa-assets-dark.config.ts && node scripts/make-icons-circular.js",
|
||||
"dev": "bash scripts/dev.sh",
|
||||
"preview": "vite preview",
|
||||
"prepare": "svelte-kit sync || echo ''",
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
/>
|
||||
{:else if section.type === AgenticSectionType.TOOL_CALL || section.type === AgenticSectionType.TOOL_CALL_PENDING || section.type === AgenticSectionType.TOOL_CALL_STREAMING}
|
||||
<ChatMessageToolCallBlock
|
||||
attachments={message?.extra}
|
||||
attachments={section.toolResultExtras}
|
||||
isExecuting={section.toolCallId !== undefined &&
|
||||
section.toolCallId === currentlyExecutingToolCallId}
|
||||
{isStreaming}
|
||||
|
||||
+2
-6
@@ -139,12 +139,8 @@
|
||||
|
||||
async function handleExportConfirm(selectedConversations: DatabaseConversation[]) {
|
||||
try {
|
||||
const allData: ExportedConversation[] = await Promise.all(
|
||||
selectedConversations.map(async (conv) => {
|
||||
const messages = await conversationsStore.getConversationMessages(conv.id);
|
||||
|
||||
return { conv: $state.snapshot(conv), messages: $state.snapshot(messages) };
|
||||
})
|
||||
const allData = await conversationsStore.getConversationsForExport(
|
||||
selectedConversations.map((conv) => conv.id)
|
||||
);
|
||||
|
||||
if (allData.length === 1) {
|
||||
|
||||
@@ -2,8 +2,11 @@ import type { AgenticConfig } from '$lib/types/agentic';
|
||||
|
||||
export const ATTACHMENT_SAVED_REGEX = /\[Attachment saved: ([^\]]+)\]/;
|
||||
|
||||
// JSON detection: trimmed content opens with an object or array literal.
|
||||
export const TOOL_RESULT_JSON_OPEN_REGEX = /^[[{]/;
|
||||
// JSON detection: an attachment placeholder also starts with `[`, but is
|
||||
// plain text (`[Attachment saved: ...]`), not an array literal. Require the
|
||||
// first array value (or the closing bracket for an empty array) to look like
|
||||
// a valid JSON token before attempting JSON.parse.
|
||||
export const TOOL_RESULT_JSON_OPEN_REGEX = /^(?:\{|\[\s*(?:[[\]"{\-0-9]|true|false|null))/;
|
||||
|
||||
// Search-summary wire format used by file-glob and grep tools:
|
||||
// <matches>
|
||||
|
||||
@@ -168,15 +168,7 @@ class ConversationsStore implements ConversationsPreferencesHost {
|
||||
if (convIds.length === 0) return;
|
||||
|
||||
try {
|
||||
const fetched = await DatabaseService.getConversationsWithMessages(convIds);
|
||||
const activeId = this.activeConversation?.id;
|
||||
const overridden = fetched.get(activeId ?? '');
|
||||
|
||||
if (overridden && activeId) {
|
||||
overridden.conv = { ...this.activeConversation! };
|
||||
}
|
||||
|
||||
const exported = [...fetched.values()];
|
||||
const exported = await this.getConversationsForExport(convIds);
|
||||
|
||||
if (exported.length === 0) {
|
||||
toast.error('No conversations to export');
|
||||
@@ -365,16 +357,11 @@ class ConversationsStore implements ConversationsPreferencesHost {
|
||||
* @param convId - The conversation ID to download
|
||||
*/
|
||||
async downloadConversation(convId: string): Promise<void> {
|
||||
const conversation =
|
||||
this.activeConversation?.id === convId
|
||||
? this.activeConversation
|
||||
: await DatabaseService.getConversation(convId);
|
||||
const [exportedConversation] = await this.getConversationsForExport([convId]);
|
||||
|
||||
if (!conversation) return;
|
||||
if (!exportedConversation) return;
|
||||
|
||||
const messages = await DatabaseService.getConversationMessages(convId);
|
||||
|
||||
ConversationTransferService.downloadConversationFile({ conv: conversation, messages });
|
||||
ConversationTransferService.downloadConversationFile(exportedConversation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,6 +440,19 @@ class ConversationsStore implements ConversationsPreferencesHost {
|
||||
return await DatabaseService.getConversationMessages(convId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets conversations and their messages from the database for export.
|
||||
* @param convIds - Conversation IDs
|
||||
* @returns List of conversations with messages, ordered by the input IDs
|
||||
*/
|
||||
async getConversationsForExport(convIds: string[]): Promise<ExportedConversation[]> {
|
||||
const fetched = await DatabaseService.getConversationsWithMessages(convIds);
|
||||
|
||||
return convIds
|
||||
.map((id) => fetched.get(id))
|
||||
.filter((entry): entry is ExportedConversation => entry !== undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports conversations from provided data (without file picker)
|
||||
* @param data - Array of conversation data with messages
|
||||
|
||||
@@ -37,6 +37,10 @@ describe('classifyToolResult', () => {
|
||||
expect(classifyToolResult('["a", "b", "c"]')).toBe('json');
|
||||
});
|
||||
|
||||
it('classifies a nested JSON array', () => {
|
||||
expect(classifyToolResult('[[1, 2], [3, 4]]')).toBe('json');
|
||||
});
|
||||
|
||||
it('classifies a pretty-printed JSON object', () => {
|
||||
expect(classifyToolResult('{\n "key": "value"\n}')).toBe('json');
|
||||
});
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
vi.mock('$lib/services/database.service', () => ({
|
||||
DatabaseService: { getConversationsWithMessages: vi.fn() }
|
||||
}));
|
||||
|
||||
import { MessageRole, MessageType } from '$lib/enums';
|
||||
import { ConversationTransferService } from '$lib/services/conversation-transfer.service';
|
||||
import { DatabaseService } from '$lib/services/database.service';
|
||||
import { conversationsStore } from '$lib/stores/conversations/index.svelte';
|
||||
import type { DatabaseConversation, DatabaseMessage } from '$lib/types/database';
|
||||
import { filterByLeafNodeId } from '$lib/utils/branching';
|
||||
|
||||
/**
|
||||
* Reproduces the exported-conversation bug:
|
||||
*
|
||||
* A conversation created in the current page session keeps `currNode: ''` in the
|
||||
* sidebar list, because that list is only loaded at init while IndexedDB is stamped
|
||||
* on every message insert.
|
||||
*
|
||||
* Exporting from the cached record resulted in no branch pointer, and importing
|
||||
* the file showed every branch at once.
|
||||
*/
|
||||
|
||||
const fetchMock = vi.mocked(DatabaseService.getConversationsWithMessages);
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
const CONV_ID = 'c1';
|
||||
|
||||
function message(
|
||||
id: string,
|
||||
parent: string | null,
|
||||
timestamp: number,
|
||||
role: MessageRole,
|
||||
type: MessageType = MessageType.TEXT
|
||||
): DatabaseMessage {
|
||||
return {
|
||||
children: [],
|
||||
content: id,
|
||||
convId: CONV_ID,
|
||||
id,
|
||||
parent,
|
||||
role,
|
||||
timestamp,
|
||||
toolCalls: '',
|
||||
type
|
||||
} as DatabaseMessage;
|
||||
}
|
||||
|
||||
/** root -> u1 -> a1 -> { u2a -> a2a (older) | u2b -> a2b (newer) } */
|
||||
function branchedMessages(): DatabaseMessage[] {
|
||||
const messages = [
|
||||
message('root', null, 10, MessageRole.USER, MessageType.ROOT),
|
||||
message('u1', 'root', 20, MessageRole.USER),
|
||||
message('a1', 'u1', 30, MessageRole.ASSISTANT),
|
||||
message('u2a', 'a1', 40, MessageRole.USER),
|
||||
message('a2a', 'u2a', 50, MessageRole.ASSISTANT),
|
||||
message('u2b', 'a1', 60, MessageRole.USER),
|
||||
message('a2b', 'u2b', 70, MessageRole.ASSISTANT)
|
||||
];
|
||||
|
||||
for (const m of messages) {
|
||||
m.children = messages.filter((c) => c.parent === m.id).map((c) => c.id);
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
/** A second conversation with a single linear path: root -> u1 -> a1. */
|
||||
function linearMessages(convId: string): DatabaseMessage[] {
|
||||
return [
|
||||
{ ...message('root', null, 10, MessageRole.USER, MessageType.ROOT), children: ['u1'], convId },
|
||||
{ ...message('u1', 'root', 20, MessageRole.USER), children: ['a1'], convId },
|
||||
{ ...message('a1', 'u1', 30, MessageRole.ASSISTANT), convId }
|
||||
];
|
||||
}
|
||||
|
||||
function conversation(currNode: string, id: string = CONV_ID): DatabaseConversation {
|
||||
return { currNode, id, lastModified: 100, name: `Chat ${id}` };
|
||||
}
|
||||
|
||||
/** Mirrors `conversationsStore.loadConversation` */
|
||||
function displayedIds(imported: { conv: DatabaseConversation; messages: DatabaseMessage[] }) {
|
||||
if (imported.conv.currNode) {
|
||||
return filterByLeafNodeId(imported.messages, imported.conv.currNode, false).map((m) => m.id);
|
||||
}
|
||||
|
||||
return imported.messages.map((m) => m.id);
|
||||
}
|
||||
|
||||
/** Export then re-import */
|
||||
function roundTrip(conv: DatabaseConversation) {
|
||||
const jsonl = ConversationTransferService.serializeSessionToJsonl({
|
||||
conv,
|
||||
messages: branchedMessages()
|
||||
});
|
||||
const [imported] = ConversationTransferService.parseSessionsJsonl(jsonl);
|
||||
|
||||
return { imported, sessionLine: JSON.parse(jsonl.split('\n')[0]) };
|
||||
}
|
||||
|
||||
describe('conversation export source', () => {
|
||||
it('reads the database record rather than the stale sidebar list', async () => {
|
||||
conversationsStore.conversations = [conversation('')];
|
||||
|
||||
fetchMock.mockResolvedValue(
|
||||
new Map([[CONV_ID, { conv: conversation('a2a'), messages: branchedMessages() }]])
|
||||
);
|
||||
|
||||
const [exported] = await conversationsStore.getConversationsForExport([CONV_ID]);
|
||||
|
||||
expect(exported.conv.currNode).toBe('a2a');
|
||||
expect(conversationsStore.conversations[0].currNode).toBe('');
|
||||
});
|
||||
|
||||
it('reads every selected conversation from the database on bulk export', async () => {
|
||||
conversationsStore.conversations = [conversation(''), conversation('', 'c2')];
|
||||
conversationsStore.activeConversation = conversation('');
|
||||
|
||||
fetchMock.mockResolvedValue(
|
||||
new Map([
|
||||
['c2', { conv: conversation('a1', 'c2'), messages: linearMessages('c2') }],
|
||||
[CONV_ID, { conv: conversation('a2a'), messages: branchedMessages() }]
|
||||
])
|
||||
);
|
||||
|
||||
const archive = vi
|
||||
.spyOn(ConversationTransferService, 'downloadConversationsArchive')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
await conversationsStore.bulkExportConversations([CONV_ID, 'c2']);
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith([CONV_ID, 'c2']);
|
||||
expect(archive).toHaveBeenCalledTimes(1);
|
||||
|
||||
const payload = archive.mock.calls[0][0];
|
||||
|
||||
expect(payload.map((entry) => entry.conv.id)).toEqual([CONV_ID, 'c2']);
|
||||
// Each entry carries its own database currNode.
|
||||
expect(payload.map((entry) => entry.conv.currNode)).toEqual(['a2a', 'a1']);
|
||||
expect(payload[1].messages.map((m: DatabaseMessage) => m.id)).toEqual(['root', 'u1', 'a1']);
|
||||
|
||||
archive.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('exported conversation branch pointer', () => {
|
||||
it('carries the database currNode, so the import restores the current branch', () => {
|
||||
// The user regenerated to create a2b, then switched back to the a2a branch,
|
||||
// so the stored leaf is NOT the newest message.
|
||||
const { imported, sessionLine } = roundTrip(conversation('a2a'));
|
||||
|
||||
expect(sessionLine.currNode).toBe('a2a');
|
||||
expect(displayedIds(imported)).toEqual(['u1', 'a1', 'u2a', 'a2a']);
|
||||
expect(imported.messages.map((m: DatabaseMessage) => m.id).sort()).toEqual([
|
||||
'a1',
|
||||
'a2a',
|
||||
'a2b',
|
||||
'root',
|
||||
'u1',
|
||||
'u2a',
|
||||
'u2b'
|
||||
]);
|
||||
});
|
||||
|
||||
it('shows every branch on import when the cache entry exported an empty currNode', () => {
|
||||
const { imported, sessionLine } = roundTrip(conversation(''));
|
||||
|
||||
expect(sessionLine.currNode).toBe('');
|
||||
expect(displayedIds(imported)).toEqual(['root', 'u1', 'a1', 'u2a', 'a2a', 'u2b', 'a2b']);
|
||||
});
|
||||
});
|
||||
Vendored
+1
-1
@@ -43,7 +43,7 @@ if (LLAMA_BUILD_BORINGSSL)
|
||||
set(FIPS OFF CACHE BOOL "Enable FIPS (BoringSSL)")
|
||||
|
||||
set(BORINGSSL_GIT "https://boringssl.googlesource.com/boringssl" CACHE STRING "BoringSSL git repository")
|
||||
set(BORINGSSL_VERSION "0.20260813.0" CACHE STRING "BoringSSL version")
|
||||
set(BORINGSSL_VERSION "0.20260903.0" CACHE STRING "BoringSSL version")
|
||||
|
||||
message(STATUS "Fetching BoringSSL version ${BORINGSSL_VERSION}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user