y83 projects / gpu / opencl

Локальный LLM на Adreno 830 без root и без обходных микросервисов

работает · 2026

llama.cpp умеет считать на OpenCL, но на Android драйвер Qualcomm лежит вне пространства компоновщика Termux, q8_0 KV роняет ядро, а неправильное число потоков съедает выигрыш GPU. Этот проект собирает рабочий llama-server вокруг реального устройства: ICD, драйвер, Q4_0, Adreno-ядра, f16 KV, четыре закреплённых CPU-потока, warmup и кэш системного промпта.

pp512 (prefill)
663 ± 11 t/s (×27 к CPU)
генерация
39–45 t/s
prompt cache
0,1 с против 25 с
устройство
Adreno 830 · 12 ГБ RAM

инженерный контур

GPU-ускорение доведено до рабочего сценария, а не до одного теста

Задача

Получить от llama-server на Termux не «GPU установлен», а стабильный диалог с приемлемым временем ответа на Snapdragon 8 Elite. Встроенный OpenCL-бэкенд не стартовал из-за ICD и зависимостей драйвера, а первые рабочие флаги давали нестабильную генерацию.

Решение

Собственная сборка llama.cpp с Adreno-ядрами, Q4_0, f16 KV-кэшем, SCHED_NO_REALLOC и XMEM_GEMM, плюс runtime-контур Termux с warmup и prompt cache. Сервер прогревается до первого запроса, поэтому OpenCode и другие агенты не платят полную цену prefill за каждый системный промпт.

Граница

Это точечная оптимизация под Adreno 830. В Мэри OpenCL проверен на отдельном телефоне с Adreno 825: там используется другой llama-контур и другие замеры, их нельзя смешивать.

как устроено

Из чего собран рабочий контур

Каждый слой решает конкретную проблему Android, Qualcomm или планировщика llama.cpp.

Драйвер и OpenCL

ICD-запись для Adreno

Termux получает собственный указатель на /vendor/lib64/libOpenCL_adreno.so и не зависит от сломанного clvk-адаптера.

  • icd

Видимый backend

Termux-сервис и llama проверяют, какой libggml-бэкенд реально загружен в процессе, а не верят декларации vulkaninfo.

  • opencl

Adreno kernels

GGML_OPENCL_USE_ADRENO_KERNELS=ON и XMEM_GEMM включают Qualcomm-специфичные пути вместо generic OpenCL.

  • gpu

Модель и память

Q4_0 как основной квант

На Adreno 830 Q4_0 быстрее Q4_K_M и Q8_0 по prefill и держит стабильную генерацию.

  • q4_0

f16 KV-кэш

q8_0 при GPU offload приводит к SET_ROWS; f16 убирает падение, flash-attn отключается на этом бэкенде.

  • kv cache

Переиспользование буферов

SCHED_NO_REALLOC убирает лишние аллокации во время генерации и поднимает tg128 примерно на 16%.

  • scheduler

Ответ для агентов

Warmup перед первым запросом

Модель прогревается заранее, поэтому OpenCode и другие клиенты не стартуют с холодного prefill.

  • warmup

Prompt cache

KV-кэш системного промпта переиспользуется между запросами: 0,1 с против 25 с на повторном одинаковом префиксе.

  • cache

Четыре CPU-потока

Потоки закреплены на ядрах 0–3: восемь потоков давали регрессию генерации из-за синхронизации кластеров Snapdragon 8 Elite.

  • threads

как проверялось

От cold start до повторного запроса

Каждый шаг подтверждается на устройстве, а не только по флагам сборки.

01

Сборка

llama.cpp собирается с OpenCL, Adreno-ядрами, f16 KV и SCHED_NO_REALLOC.

02

Проверка драйвера

clinfo и /proc показывают, что процесс действительно загрузил libggml-opencl.

03

Прогрев

Сервер загружает Q4_0 и держит prompt cache готовым к агенту.

04

Замер

pp512, pp2048 и генерация измеряются отдельно на CPU и GPU.

результаты

663

t/s pp512

Adreno 830, Q4_0
535

t/s pp2048

тот же активный контур
44,8

t/s генерация

диапазон 39–45 t/s
240×

повторный prompt

prompt cache, 0,1 с против 25 с

Цифры сверены с кодом проекта 2026-10-05.

технологии

Из чего собрано

Ядро

  • llama.cpp
  • ggml
  • C++
  • OpenCL

Устройство

  • Adreno 830
  • Snapdragon 8 Elite
  • 12 ГБ RAM

Сборка

  • Termux
  • clang
  • KleidiAI
  • GGML_OPENCL_USE_ADRENO_KERNELS

Runtime

  • runit
  • warmup.sh
  • prompt cache
  • 4 pinned threads

этапы

Что сделано и что дальше

Базовый GPU-контур готов; следующий шаг — длинные модели и устойчивая генерация.

этап 1

OpenCL на Adreno 830

ICD, драйвер и базовая сборка llama.cpp

этап 2

Стабильная генерация

f16 KV, отключённый flash-attn, Adreno-ядра

этап 3

Runtime для агентов

warmup, prompt cache, четыре потока и тесты OpenCode

этап 4

Масштабирование на модели 7B+

Q4_K_M на 7B запускается в 12 ГБ RAM; ведётся профилирование пропускной способности памяти и настройка батчинга для ускорения генерации

вопросы

Частые вопросы

Это форк llama.cpp?

Нет. Это Termux-контур и набор скриптов вокруг llama.cpp: сборка OpenCL, ICD, запуск сервера, warmup, кэш и диагностика. Исходники llama.cpp остаются отдельным слоем.

Почему 44,8 t/s, если генерация меняется?

Это лучший зафиксированный результат. В серии замеров tg128 и tg256 держится примерно 39–45 t/s в зависимости от длины и состояния prompt cache.

Как это связано с Мэри?

Мэри использует отдельную проверенную сборку на Adreno 825 и 1.5B QVikhr. llama-adreno — более низкоуровневый контур на Adreno 830 с prompt cache и адаптацией под OpenCode.

Y83 llama-adreno

Есть вопрос по проекту?

Не приложение, а рабочий контур локального инференса на Android: сборка llama.cpp с OpenCL, ICD Qualcomm, Adreno-ядра, f16 KV-кэш, прогрев и prompt cache. На Xiaomi Pad 8 Pro один и тот же Qwen2.5-Coder-1.5B Q4_0 даёт около 663 t/s prompt и 39–45 t/s генерации против 24 t/s prompt на CPU.

@xipovski xipovski@gmail.com
следующий проект Y83 Media