ggml-openvino: 2026.4.1 업데이트, 성능 최적화, 연산 확장 및 장치 목록 개선
요약
ggml-openvino 라이브러리가 2026.4.1 버전으로 업데이트되며, 성능 최적화와 연산 확장 기능이 대폭 개선되었습니다. 특히 Qwen3.5 MoE 지원과 상세 추론 프로파일링 추가가 주요 내용입니다. 또한 OpenVINO 장치 목록 관리 및 메모리 보고 기능이 강화되어 안정성이 높아졌습니다.
핵심 포인트
- Qwen3.5 MoE 성능 최적화 및 통합 (OpenVINO)
- 상세 추론 프로파일링 및 단일 시퀀스 상태 최적화 구현
- OpenVINO 장치 목록 관리 및 메모리 보고 기능 개선으로 안정성 향상
ggml-openvino: 2026.4.1 업데이트, 성능 최적화, 연산 확장 및 장치 목록 개선. (#29852)
- ggml-openvino : Qwen3.5 MoE 성능 (#312)
ravi9#312 병합:
- ggml-openvino: 상세 추론 프로파일링 추가 (Yu, Zijun)
- ggml-openvino: 기본값으로 원격 출력 텐서 사용 (Yu, Zijun)
- ggml-openvino: 단일 시퀀스 순환 상태 최적화 (Yu, Zijun)
- opt1: 단일 시퀀스를 위한 순환 리셋 제거, opt2: 직접 gdn 출력 (병렬 시퀀스 중단) (Yu, Zijun)
- 병렬 시퀀스 수정 (Yu, Zijun)
- ggml-openvino: 그래프 캐시 키 단순화 (ynimmaga)
- qwen35 단일 시퀀스를 위한 stateful 활성화 (Yu, Zijun)
- 리베이스 후 수정 (Yu, Zijun)
- k-requant 옵션 q4_asym64 추가 (Yu, Zijun)
- qwen35 llama-bench -p 0 수정 (Yu, Zijun)
- RESHAPE 변환 단순화 (Yu, Zijun)
- openvino: MoE 라우팅 통합 (Yu, Zijun)
- openvino: 통합 GDN qk 정규화 (Yu, Zijun)
- openvino: 기본값으로 GPU MoE 통합 활성화 (Yu, Zijun)
- ggml-openvino: 디스크에 캐시된 컴파일 모델을 직접 가져오기 위해 cache_only 모드 추가 (Yu, Zijun)
- openvino : 장치 할당 제한을 ggml에 보고 (Łukasz Ślusarczyk)
- 윈도우 빌드 수정 (Yu, Zijun)
공동 작성자: ynimmaga [email protected]
공동 작성자: Łukasz Ślusarczyk [email protected]
-
ggml-openvino: 컴파일된 모델 캐시 문서 업데이트
-
openvino: PRD를 준수하는 장치 열거 및 메모리 보고 구현
-
openvino: 리뷰에서 발생한 다중 장치 목록 문제 수정
-
GGML_OPENVINO_DEVICE에 의해 선택된 장치만 GPU로 보고되며, 다른 OpenVINO 장치는 IGPU로 보고되어 llama.cpp가 해당 장치로 오프로드하지 않습니다. 비선택 장치를 초기화할 경우 경고가 기록됩니다.
-
장치 이름 OPENVINO를 다시 지정하고 설명에 OpenVINO ID를 표시합니다. 원시 "CPU" 이름이 ggml CPU 백엔드를 가렸습니다._
-
GPU.N 지원: 선택된 장치의 자체 컨텍스트에서 OpenCL 큐를 생성하고, "GPU"/"NPU" 문자열 비교를 ggml_openvino_is_gpu()/ggml_openvino_is_npu()로 대체합니다.
-
사용 불가능한 GGML_OPENVINO_DEVICE는 이제 사용 가능한 장치를 나열하는 오류가 되며, CPU로 조용히 폴백하지 않습니다.
-
메모리: iGPU/NPU의 여유 메모리를 시스템 가용 메모리로 제한하고, 플러그인이 메모리 속성을 갖지 못할 경우 0/0 대신 시스템 메모리로 폴백하며, GPU 사용 시 호스트 USM 할당을 무시합니다.
-
OpenCL 설정이 실패하더라도 잠금(lock) 하에 장치 구성을 한 번 초기화합니다.
-
비선택 장치에 대한 supports_op 반환 유형을 수정했습니다 (빌드 오류)._
- openvino: 선택된 장치 플랫폼에서 USM 진입점을 가져옵니다.
clGetExtensionFunctionAddressForPlatform은 clGetPlatformIDs가 반환하는 첫 번째 플랫폼에서 호출되었습니다. 이 함수가 반환하는 주소는 쿼리한 플랫폼에만 유효하며, 첫 번째 플랫폼이 항상 OpenVINO가 선택한 장치를 보유하는 것은 아닙니다.
첫 번째 플랫폼이 다른 공급업체의 호스트인 경우 조회는 null을 반환하고, 이후 GPU 버퍼에 대한 모든 읽기, 쓰기 및 memset은 "clEnqueueMemcpyINTEL not available"로 실패합니다.
init()에서 OpenVINO가 선택한 장치의 플랫폼에서 두 진입점을 모두 찾고, 이를 명령 큐 옆의 장치 구성에 유지해야 합니다.
보조: Claude Opus 5
- openvino: fused gate_up 가중치가 있는 모델의 MoE 전문가를 통합합니다.
FuseMoeCompressed는 게이트(gate)와 업(up) 프로젝션이 분리된 GatherMatmul 연산자만을 처리합니다. gemma-4는 이 둘을 하나의 전문가 가중치로 묶고 GEMM 이후에 결과를 분할하므로, MoE 블록은 비융합 상태를 유지하며 토큰별 GEMV로 전문가 GEMM을 실행합니다.
FuseMoeCompressedFusedGateUp을 추가하여 해당 형태(하나의 GatherMatmul -> Slice/Slice -> Gelu(ERF) -> Multiply)와 일치시키고, 이를 동일한 MOECompressed 연산자에 통합하며 GEGLU_ERF를 사용해 GEMM3_SWIGLU로 접습니다. 융합된 가중치, 스케일 및 제로 포인트는 원시 바이트 복사를 통해 게이트/업 절반으로 분할되는데, 이는 그래프 Slice가 StridedSlice로 재작성되고 상수가 접혀지면서 참조 평가기가 서브바이트 타입에서 충돌하기 때문입니다.
gemma-4는 또한 라우터 가중치 이전에 전문가별 출력 스케일을 적용합니다. MOECompressed는 하나의 전문가 가중치만 사용하므로, 해당 스케일은 라우팅 가중치에 접혀지며 이는 정확합니다.
이 연산자는 제로 포인트를 가중치 포트에서 바로 읽어오기 때문에 정수 Constant가 필요하며, 따라서 매처는 이를 요구하고 네이티브 양자화된 전문가(정확한 f16 zp)는 비융합 경로에 남겨둡니다.
gemma-4-26B-A4B를 Arc B390에서 GGML_OPENVINO_REQUANT_KQUANT=q4_asym64_all로, llama-bench -p 512 -n 128 -r 2 기준으로, GGML_OPENVINO_MOE_OP=0 기준선과 비교했을 때: pp512는 66.16 -> 1608.73 t/s로, tg128은 25.94 -> 26.46 t/s로 측정되었습니다. 12 청크에 걸친 Perplexity는 변하지 않았습니다 (비융합 시 1451.3 +/- 177.9 대 융합 시 1427.6 +/- 175.1).
해당 양자화 옵션이 없거나, 게이트/업 가중치가 분리된 모델 또는 CPU에서는 효과가 없습니다. test-backend-ops -b OPENVINO0은 이 커밋으로 인해 변경되지 않았습니다: 두 개의 MUL_MAT_ID m_v 케이스가 실패하며, 이는 수정하지 않은 기본값에서도 동일합니다.
- openvino: 상태 저장 실행(stateful execution) 하에서 MoE가 작동하도록 랭크-3 축 처리 오류를 수정함
Stateful execution은 선행하는 size-1 배치 차원(batch dim)을 제거하므로, OV 텐서는 랭크가 3이 되지만 GgmlOvDecoder::get_shape/get_stride는 여전히 GGML_MAX_DIMS=4의 역순 항목들을 보고합니다. 여러 MoE 연산(op)들이 이 메타데이터로부터 OV 축 인덱스를 직접 파생하기 때문에, 잘못된 축을 선택했습니다. GGML_OPENVINO_STATEFUL_EXECUTION=1인 MoE 모델은 그래프를 구축하는 과정에서 중단됩니다:
Check 'is_axis_valid(axis, r)' failed at src/core/src/validation_util.cpp:336
While validating node 'opset11::TopK ... _ffn_moe_probs ...'
Axis 3 out of the tensor rank range [-3, 2].
해결 방안은 전반적으로 다음과 같습니다: 실제 OV 랭크에서 축을 가져오거나, 메타데이터로 파생된 축을 metadata_rank - actual_rank만큼 낮춥니다.
argsort.cpp의 라우터 top-k 축은 랭크 3에서 2이며, 3이 아닙니다. 이것이 위에서 언급한 중단 사례입니다.
add.cpp에서 MoE 전문가 합산 우회(expert-sum bypass)는 8-ADD 체인을 단일 ReduceSum으로 압축하며 하드코딩된 축 2를 사용합니다. 이는 랭크 3에서 n_embd를 감소시키고, 대신 전문가 축을 감소시켜야 합니다. 이제 랭크 2가 되고, 다음처럼 랭크 3에서 Unsqueeze를 수행합니다.
get_rows.cpp에서 하드코딩된 {0,1}을 압축하는 과정은 배치 차원이 1일 때마다(즉, 모든 디코드 단계) 이를 제거합니다. 대신 뒤쪽 두 차원(trailing two dims)으로 축소해야 합니다.
mul_mat_id.cpp는 실제 랭크로 리쉐이프 차원을 선택하고, 배치 차원을 다시 추가하는 후행 Unsqueeze를 건너뜁니다.
view.cpp에서 전문가 평면 슬라이스(expert-plane slice)는 Slice 축, dst_ov_axis, ShapeOf+Gather 인덱스, 그리고 Reshape 대상 모두 랭크 4였습니다.
utils.cpp의 'process_view_input_new'의
Stateless는 구조적으로 변경되지 않았습니다. 모든 편집은 실제 rank에 의해 제어되므로, axis_shift == 0은 이전 코드를 정확하게 재현합니다. dense gemma-4-E2B, granite-1b-a400m 및 gemma-4-26B-A4B에 대해 OV-CPU에서 greedy 출력을 수정되지 않은 기본값과 비교하여 확인했으며, 모두 동일했습니다.
granite-1b-a400m은 이 변경 전에는 위 오류로 인해 OV-CPU에서 중단되었으나, 이후에는 stateless와 바이트 단위로 동일한 출력을 생성합니다. dense gemma-4-E2B는 이전과 이후 모두 stateful과 비교하여 동일합니다. test-backend-ops -b OPENVINO0은 변경되지 않았습니다: 두 개의 사전 존재하는 MUL_MAT_ID m_v 케이스가 실패하며, 이는 수정되지 않은 기본값에서도 동일합니다.
gemma-4-26B-A4B는 여기서 정확성 검증에 적합하지 않습니다. OV에서는 이미 몇 토큰 진행된 시점부터 degenerate repetition(퇴화 반복) 상태로 빠지며, stateless와 stateful 모두 마찬가지입니다. 그리고 두 모드는 토큰 단위로 일치하는 대신 퇴화 영역 내부 어딘가에서 분기됩니다. 각 모드는 실행 간에 자체 재현성이 있습니다.
알려진 제한 사항: FuseMoeCompressedFusedGateUp은 rank-3 그래프와 일치하지 않으므로, GGML_OPENVINO_STATEFUL_EXECUTION=1로 MoE 모델을 실행하면 prefill 융합(fusion)을 잃는 대신 decode를 얻게 됩니다. gemma-4-26B-A4B on Arc B390, GGML_OPENVINO_REQUANT_KQUANT=q4_asym64_all, llama-bench -p 512 -n 128 -r 2:
unfused (GGML_OPENVINO_MOE_OP=0) pp512 66.16 tg128 25.94
fused, stateless (default) pp512 1608.73 tg128 26.46
fused, stateful pp512 66.18 tg128 29.91
Stateful은 선택적(opt-in)이며 기본적으로 비활성화되어 있고, MoE는 이전에 여기서 전혀 실행되지 않았기 때문에 이전에 작동했던 것이 역행하지 않습니다. pass를 rank 3과 일치시키는 것이 후속 작업입니다.
-
OpenVINO 백엔드: 노드_idx, src_idx, 노드 유형을 사용하도록 그래프 캐시 업그레이드
-
ggml-openvino : 더 포괄적인 conv fusion 활성화
-
conv ops 활성화
-
커널 크기 0 거부 및 IM2COL_3D 지원
-
openvino : GPU 원격 컨텍스트를 생성할 수 없을 때 중단
init()에서 오류를 기록하고 반환하여 장치 이름은 GPU로 남지만 remote_context는 비어 있게 됩니다. 이 원격 버퍼와 텐서 경로는 장치가 GPU인 경우에만 검증(assert)을 수행한 후, 그 빈 선택적 값(empty optional)을 역참조합니다.
이러한 경로들은 호스트 폴백(host fallback)이 없으며, OpenVINO가 나열한 장치는 작동하는 OpenCL 컨텍스트를 가지고 있어야 하므로, 계속 진행하기보다는 중단해야 합니다. 전체적으로 손상된 OpenCL 스택은 이미 장치 가용성 검사에서 CPU로 폴백되면서 더 일찍 포착됩니다.
Assisted-by: Claude Opus 5
- openvino : 빌드 경고 수정
OpenVINO RTTI 매크로의 단일 인자 형태가 의도된 방식이지만, 해당 선택기(selector) 매크로는 VA_ARGS를 비워두어 -Wpedantic이 모든 패스 및 연산자 헤더에서 보고하게 됩니다. 이 경고는 ggml-cuda와 ggml-sycl이 자체 서드파티 경고에 대해 이미 하는 것처럼, 이 백엔드에 대해서만 꺼주세요.
또한 GGML_ABORT 주변의 break와 죽은 할당(dead assignment)을 제거해야 하는데, 이는 noreturn입니다.
Assisted-by: Claude Opus 5
-
OpenVINO Backend: 일반적인 MTMD 연산자 지원
-
ggml-openvino: 리셰이핑 뷰에 자체 ov::Tensor 제공
-
ggml-openvino : f32에서 HARDSIGMOID 및 EXPM1 계산
HARDSIGMOID는 입력 타입에서 1/6 상수를 사용했는데, 이는 bf16에서 정확하지 않으며, EXPM1은 f16에서 작은 입력에 대해 정밀도를 잃었습니다. 둘 다 이제 f32에서 계산하고 다시 변환하며, NPU의 경우 f32 경로가 잘못된 결과를 제공하는 예외입니다.
GPU에서의 HARDSIGMOID/EXPM1 테스트-백엔드-연산자 실패를 수정합니다.
- ggml-openvino : 장치 선택 및 --list-devices 업데이트
--list-devices, 시작 로그, 그리고 백엔드 테스트에서 선택되는 GGML_OPENVINO_DEVICE 값과 활성 장치를 표시합니다.
OpenVINO 선택이 -dev가 아닌 GGML_OPENVINO_DEVICE를 사용함을 명확히 합니다.
- openvino : 도달할 수 없는 OpenCL 큐 검사 제거
원격 버퍼는 GPU 장치에서만 존재하며, init()에서 큐를 생성할 수 없으면 그곳에서 중단하므로, 이 호출 지점들에서는 큐가 절대 null이 아닙니다.
Assisted-by: Claude Opus 5
-
openvino: OpenVINO를 2026.4.1로, GPU 드라이버를 26.35.39758.10으로 업데이트
-
docs: OpenVINO 검증 모델 및 GPU 드라이버 버전 업데이트
-
ggml-openvino: 리셰이핑(reshaping) 뷰가 자체 텐서(tensor)를 가질 때 빈 뷰(empty views) 건너뛰기 기능 추가
GPU USM 버퍼의 끝에 제로 크기 뷰(zero-size view)가 존재할 수 있습니다 (Qwen3.5 재귀 캐시). 이를 원격 텐서(remote tensor)로 감싸면 "공유된 USM 버퍼의 크기가 더 작습니다 (0)"라는 오류가 발생합니다.
Assisted-by: Claude
- ggml-openvino: llama가 다른 그래프를 전달할 때 캐시된 디코더 재바인딩(rebind the cached decoder) 기능 추가
llama는 출력 유무에 따라 별도의 그래프를 유지합니다. llama-server는 컨텍스트 체크포인트(context checkpoints)를 위해 프롬프트를 청크(chunks)로 분할하므로, 캐시된 디코더가 다른 메모리에서 구축된 그래프와 재사용될 때 이전 청크의 입력 텐서들을 바인딩해야 합니다. 이로 인해 SWA 및 재귀 모델은 llama-cli와 llama-server에서 프롬프트의 대부분을 손실했습니다.
Assisted-by: Claude
- docs: OpenVINO 검증 모델 업데이트
위 두 가지 수정 사항을 적용하여 Lunar Lake (32 GB)에서 스모크 테스트(Smoke test)를 수행했습니다. Qwen3.5 및 gemma 모델을 다시 추가했습니다.
Assisted-by: Claude
공동 작성자: Yu, Zijun [email protected]
공동 작성자: ynimmaga [email protected]
공동 작성자: Łukasz Ślusarczyk [email protected]
공동 작성자: haarika-madaka [email protected]
공동 작성자: Mustafa Cavus [email protected]
공동 작성자: Mostafa Faheem [email protected]
__
웹사이트:
AI 자동 생성 콘텐츠
본 콘텐츠는 llama.cpp Releases의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기