1. 서론 (Introduction)
최근 극단적인 양자화 기법을 적용한 1.58-bit 대형 언어 모델(BitNet b1.58)이 등장하며 엣지 디바이스(Edge Device)에서의 온디바이스 AI 구동 가능성이 대두되었다.
본 연구에서는 삼성 Galaxy A35 (Exynos 1380, ARMv8.2-A) 및 PRoot/Termux 환경에서 BitNet.cpp 추론 엔진을 구동하는 실험을 진행하였다.
첫 도전 : 2026. 3. 23. 쓰디쓴 한계를 맛보다...
#4. BitNet과 A35의 한계.. 갤럭시 A35 x BitNet.cpp (실패기이자 학습기)
#4. BitNet과 A35의 한계.. 갤럭시 A35 x BitNet.cpp (실패기이자 학습기)
결론 : 멍멍이 같이 실패... 내가 직접 Termux + Android + A35(Exynos 1380) 환경에서BitNet-b1.58-2B-4T(i2_s)를 빌드부터 실행까지 끝까지 밀어붙인 실전 기록이다.결론부터 말하면: BitNet i2_s는 “빌드는 성공할
uno-kim.tistory.com
두 번째 도전 : 2026. 4. 21. 한달만에 도전! 이땐 Proot + 우분투 환경 + 콘다 환경과같은 폐쇄된 곳에서 진행
#4. [Bitnet.cpp]모바일 환경에서 컨테이너띄우고 빌드
#4. [Bitnet.cpp]모바일 환경에서 컨테이너띄우고 빌드
안녕하세요. 지난번 Edge Device 환경에서 Bitnet.cpp를 돌리고자 했지만 실패했었습니다.이번에 많은 프로젝트를 진행하면서 cpp 빌드도 많이 돌려봤는데요, 환경설정이 가장 어려웠습니다.그럴때마
uno-kim.tistory.com
그러나 추론 과정에서 모델이 논리적인 텍스트를 생성하지 못하고 특정 토큰을 무한 반복하는 출력 붕괴(Degeneration, 소위 'Word Salad') 현상이 발생하였다.


본 보고서는 해당 현상의 근본 원인을 규명하기 위해 수행한 환경 변인 통제, 하드웨어 결함 검증, 그리고 C++ 양자화 커널의 역공학(Reverse Engineering) 과정을 상세히 기술한다.
2. 가설 수립 및 교차 검증
초기에는 출력 붕괴 현상의 원인으로 모바일 프로세서 특유의 하드웨어 및 OS 레벨의 제약을 의심하였으며, 이를 검증하기 위해 4단계의 엄격한 변인 통제 실험을 수행하였다.
- 가설 1: 안드로이드 네이티브 OS 및 빌드 툴체인 충돌
- 검증: 안드로이드 기본 터미널(Termux) 환경의 NDK 컴파일러가 기계어를 생성하는 과정에서 메모리 정렬 등의 빌드 손상이 발생했을 가능성을 의심하였다. 이를 통제하기 위해 안드로이드 가상화 레이어인 PRoot 기반의 Ubuntu 환경을 구축하고, Miniforge(Conda)를 통해 독립적이고 폐쇄적인 x86 수준의 리눅스 빌드 환경을 강제하였다.
- 결과: 완전히 통제된 환경에서 재빌드를 수행했음에도 동일한 출력 붕괴 현상이 발생하여, OS 가상화 및 빌드 툴체인 가설을 기각하였다.
- #4. [Bitnet.cpp]모바일 환경에서 컨테이너띄우고 빌드
- 가설 2: Big.LITTLE 아키텍처의 캐시 불일치
- 검증: 모바일 AP 특유의 이기종 코어(A78, A55) 간 컨텍스트 스위칭 시 L1/L2 캐시 오염이 발생할 가능성을 검증하였다. PRoot 실행 단계부터 taskset 명령어를 통해 단일 고성능 코어로 스레드 친화도를 고정하였고, 추론 엔진(llama.cpp)의 인자 역시 단일 스레드(-t 1)로 제한하여 코어 간 핑퐁 현상을 물리적으로 차단하였다.
- 결과: 스레드 동시성 문제를 완벽히 통제했음에도 현상이 유지되어 가설을 기각하였다.
- [분석/검증-1] BitNet.cpp 텐서 연산 붕괴(텐서 오류) 현상 분석 : Big.LITTLE 구조의 캐시 불일치
- 가설 3: ARM NEON SIMD 및 DotProd 가속기 결함
- 검증: Exynos의 16비트 누산기 오버플로우나 FPU 연산 결함을 의심하여, 하드웨어 가속기(NEON)를 비활성화하고자 하였다. CMake 빌드 단계에서 -DGGML_NEON=OFF 및 -march=armv8-a+nosimd 플래그를 주입하여 스칼라 모드 빌드를 유도하였다.
- 결과: 출력 붕괴가 여전히 발생하였다. 엔진의 런타임 로그를 딥다이브한 결과, 시스템 정보에서 NEON = 1이 출력됨을 확인하였다. 즉, 빌드 플래그를 통한 정적 차단이 OS의 동적 하드웨어 감지에 의해 우회되고 있었음을 발견하였다.
- [분석/검증-2] BitNet.cpp 텐서 연산 붕괴 현상 분석 : ARM 아키텍처 점곱 가속기의 하드웨어 결함 교차 검증
- 가설 4: 런타임 하드웨어 감지 강제 차단 및 스칼라 폴백(Scalar Fallback) 이식
- 검증: C++ 추론 엔진 내부(ggml.c)에서 안드로이드 커널에 물리적 하드웨어 스펙을 질의하는 함수(getauxval(AT_HWCAP))가 강제로 NEON을 활성화시키는 것을 근본 원인으로 특정하였다. 이를 우회하기 위해 파이썬 인젝션 스크립트를 자체 개발하여, C++ 소스 코드 레벨에서 GGML_NO_NEON 환경변수 주입 시 런타임에 즉시 return 0;을 반환하도록 로직을 변조하였다. 또한, 가속기가 꺼졌을 때 실행되는 스칼라 폴백 코드를 AVX2 기반의 메모리 인터리빙 구조에 맞게 재작성하였다.
- 결과: 런타임 검증 로그에서 NEON = 0으로 가속기가 완벽히 차단되었음을 확인하였으며, 모델이 논리적인 영어 문장("Paris is a city that is known for...")을 정상적으로 생성하며 출력 붕괴 현상이 완벽히 해결되었다.
- [분석/검증-3] BitNet.cpp ARM 커널 재작성 : 스칼라 폴백구현을 통한 최종 검증
결론: 하드웨어, 스케줄러, 가상화 환경에 대한 모든 변인을 통제했음에도 문제가 지속되었다. 이는 시스템 아키텍처의 문제가 아닌, 1.58-bit (i2_s) 압축 데이터를 해독하고 점곱을 수행하는 C++ 스칼라 폴백 코드 자체의 수학적, 구조적 결함임을 시사한다.
3. 근본 원인 분석
문제의 원인은 PC(x86 AVX2)를 기준으로 설계된 GGUF 양자화 파일의 메모리 레이아웃을 ARM 스칼라 환경에서 잘못 해석한 것에 있었다. 역공학을 통해 확인한 두 가지 치명적인 오류는 다음과 같다.
3.1. 메모리 인터리빙 구조의 불일치
AVX2 인트린직(Intrinsic) 코드를 분석한 결과, i2_s 포맷은 데이터를 선형으로 압축하지 않는다. SIMD 레지스터의 처리량을 극대화하기 위해 활성화 값 배열은 32바이트 단위로 교차 배치되어 있다.
기존의 직관적인 스칼라 구현은 py[k * 4 + 0]과 같이 선형적(Linear)인 메모리 접근을 수행하였으나, 실제 AVX2 규격의 GGUF 파일은 py[k], py[k + 32], py[k + 64], py[k + 96]의 오프셋을 요구한다. 이로 인해 스칼라 커널은 전혀 엉뚱한 활성화 값을 메모리에서 페치하여 곱셈을 수행하고 있었다.
3.2. Ternary 매핑의 수학적 최적화 오해
BitNet의 가중치는 {-1, 0, 1}의 삼진값을 가진다. 2비트로 압축된 값(0, 1, 2)을 추출한 뒤, 논리적으로는 값에서 1을 빼서(v - 1) 복원해야 한다고 추론하기 쉽다.
그러나 AVX2 최적화 커널인 _mm256_maddubs_epi16 명령어의 동작을 디스어셈블리 수준에서 분석한 결과, 가중치 값(0, 1, 2)을 -1 연산 없이 활성화 값 y에 그대로 곱하고 있었다.
이는 활성화 값의 분포가 영평균을 따른다는 모델의 수학적 성질을 이용한 것이다.

이 성립하므로, 뺄셈 연산 사이클을 아끼기 위해 의도적으로 매핑을 생략한 구조다. 이를 파악하지 못하고 스칼라 폴백에서 명시적인 매핑 테이블이나 -1 연산을 추가할 경우 연산 모델이 완전히 붕괴된다.
4. 커널 역공학 및 스칼라 폴백 패치
앞선 분석을 바탕으로, AVX2의 SIMD 메모리 로드 패턴과 비트 시프트 순서를 100% 동일하게 모사하는 스칼라 폴백 커널(ggml_vec_dot_i2_i8_s_1x1)을 재작성하였다.
// Patch: ggml-bitnet-mad.cpp 내 스칼라 폴백 구현부 수정
const uint8_t * x_ptr = (const uint8_t *)vx;
const int8_t * y_ptr = (const int8_t *)vy;
const int qk = 128; // AVX2 규격과 동일한 블록 사이즈 강제
const int nb = n / qk;
for (int row = 0; row < nrc; row++) {
int32_t sumi = 0;
const uint8_t * x_row = x_ptr + row * (bx / 4);
for (int b = 0; b < nb; b++) {
const uint8_t * px = x_row + b * 32; // 1블록(128 elements) = 32 bytes
const int8_t * py = y_ptr + b * qk; // 1블록 활성화 값
for (int k = 0; k < 32; k++) {
uint8_t xb = px[k];
// AVX2 _mm256_srli_epi16 처리 순서와 동일하게 MSB -> LSB 추출
int v0 = (xb >> 6) & 0x03;
int v1 = (xb >> 4) & 0x03;
int v2 = (xb >> 2) & 0x03;
int v3 = xb & 0x03;
// 인터리빙 메모리 접근 및 오프셋(0, 1, 2) 직접 곱셈 적용
sumi += v0 * py[k + 0*32];
sumi += v1 * py[k + 1*32];
sumi += v2 * py[k + 2*32];
sumi += v3 * py[k + 3*32];
}
}
// Scale은 상위 프레임워크(ggml_mul_mat)로 위임
s[row] = (float)sumi;
}
5. 결과 및 결론
재작성된 C++ 커널을 컴파일하고 NEON 가속기가 통제된 단일 스레드 환경에서 검증한 결과, 출력 붕괴 현상이 완전히 해소되었으며 "Paris. Paris is a city that is known for its rich history..."와 같은 의미론적으로 완벽한 문장이 생성됨을 확인하였다.
본 분석을 통해 이기종 아키텍처(x86 vs ARM) 간 모델 이식 시, 단순히 컴파일러의 경고를 억제하는 것을 넘어 양자화 데이터의 패킹 레이아웃과 하드웨어 인트린직의 암묵적 수학 연산 메커니즘을 정확히 동기화하는 것이 필수적임을 증명하였다.
이는 향후 1-bit LLM을 비롯한 초저정밀도 양자화 모델의 엣지 디바이스 이식 과정에서 중요한 레퍼런스로 활용될 수 있을 것이다.
긴글 읽어주셔서 감사합니다.
이젠 NEON을 쓰더라도 오류없이 나올수 있도록 수정하고 최종 마무리로 뵙겠습니다.
1편
갤럭시 A35는 이제 제껍니다. (모바일 자율 AI 에이전트: 프로젝트 AMEVA #1)
갤럭시 A35는 이제 제껍니다. (모바일 자율 AI 에이전트: 프로젝트 AMEVA #1)
당신의 폰은... 유투브 숏츠 머신인가요? 아니면 지능형 생명체인가요?안녕하세요, 멀쩡한 최신 폰을 가만히 두지 못하는 '맑눈광' 개발자입니다챗지피에서 찍어내는 프로젝트, 그리고 클로드코
uno-kim.tistory.com
2편
#0. 프로젝트를 임하는 마음가짐 및 나의 생각
[Episode 0] 1-bit의 사투: 빅테크의 '지능 독점'을 무너뜨릴 야생의 에이전트1. 사육된 지능의 시대: 우리는 '디지털 소작농'인가?지금의 AI 열풍은 기만적입니다. 구글, 오픈AI, 마이크로소프트 같은
uno-kim.tistory.com
3편
#1. 갤럭시 A35 최적화 및 시스템 셋팅 가이드
지난 글에서 왜 이 짓을 하는지 선언했다면, 이제는 행동할 때다. 30만 원짜리 보급형 스마트폰 갤럭시 A35를 단순한 장난감이 아닌, 지능을 가진 '병기'로 탈바꿈시키기 위한 인프라 구축 단계를
uno-kim.tistory.com
4편
#2. A35의 VS Code 서버 구축 및 텔레그램 신경망 이식
#2. A35의 VS Code 서버 구축 및 텔레그램 신경망 이식
이번 단계에서는 폰이 주인님의 명령을 알아듣고, 실제로 파일을 만들거나 명령을 실행하는 '팔다리'를 달아줄 겁니다.#2. 아메바의 서식지: VS Code 서버 구축과 텔레그램 신경망 연결 1단계: 텔레
uno-kim.tistory.com
5편
#3: BitNet.cpp 이식 및 1-bit LLM 가동
#3: BitNet.cpp 이식 및 1-bit LLM 가동
안녕하세요~! 요즘 일감도 없고 연봉도 안오르고 해서 계속 축축처지는 와중에도 열심히 블로그를 작성해서 하나의 거름을 뿌리는 마음으로 임해볼게요!블로그를 작성한지 벌써 5년이나 지났지
uno-kim.tistory.com
6편
#4. BitNet과 A35의 한계.. 갤럭시 A35 x BitNet.cpp (실패기이자 학습기)
#4. BitNet과 A35의 한계.. 갤럭시 A35 x BitNet.cpp (실패기이자 학습기)
결론 : 멍멍이 같이 실패... 내가 직접 Termux + Android + A35(Exynos 1380) 환경에서BitNet-b1.58-2B-4T(i2_s)를 빌드부터 실행까지 끝까지 밀어붙인 실전 기록이다.결론부터 말하면: BitNet i2_s는 “빌드는 성공할
uno-kim.tistory.com
7편
#5. [Bitnet.cpp]모바일 환경에서 컨테이너띄우고 빌드
#4. [Bitnet.cpp]모바일 환경에서 컨테이너띄우고 빌드
안녕하세요. 지난번 Edge Device 환경에서 Bitnet.cpp를 돌리고자 했지만 실패했었습니다.이번에 많은 프로젝트를 진행하면서 cpp 빌드도 많이 돌려봤는데요, 환경설정이 가장 어려웠습니다.그럴때마
uno-kim.tistory.com
분석/검증시리즈
1편
[분석] BitNet.cpp 1.58비트 모델의 모바일 환경 추론 실패 원인 분석
[분석] BitNet.cpp 1.58비트 모델의 모바일 환경 추론 실패 원인 분석
예전 Microsoft가 공개한 1비트 대규모 언어 모델 추론 프레임워크인 BitNet.cpp를 안드로이드 모바일 환경에 구축 및 테스트를 진행했다.의존성 패키지 설치와 CMake를 통한 C++ 커널 컴파일, 1.19GB 규모
uno-kim.tistory.com
2편
[분석/검증-1] BitNet.cpp 텐서 연산 붕괴(텐서 오류) 현상 분석 : Big.LITTLE 구조의 캐시 불일치
[분석/검증-1] BitNet.cpp 텐서 연산 붕괴(텐서 오류) 현상 분석 : Big.LITTLE 구조의 캐시 불일치
대상 기기: Samsung Galaxy A35 (Exynos 1380)현상: BitNet.cpp 추론 시 논리적 문장이 아닌 무작위 토큰이 나열되는 '워드 샐러드(Word Salad)' 발생https://uno-kim.tistory.com/454 #4. [Bitnet.cpp]모바일 환경에서 컨테이
uno-kim.tistory.com
3편
[분석/검증-2] BitNet.cpp 텐서 연산 붕괴 현상 분석 : ARM 아키텍처 점곱 가속기의 하드웨어 결함 교차 검증
[분석/검증-2] BitNet.cpp 텐서 연산 붕괴 현상 분석 : ARM 아키텍처 점곱 가속기의 하드웨어 결함 교
본 테스트의 목적은 Exynos 1380 프로세서가 지원하는 ARMv8.2-A 아키텍처의 점곱 하드웨어 가속 명령어와 C++ 컴파일러 간의 기계어 번역 충돌 여부를 격리하여 검증하는 것이다.BitNet(1.58-bit) 모델 구
uno-kim.tistory.com
4편-최종
[분석/검증-3] BitNet.cpp ARM 커널 재작성 : 스칼라 폴백구현을 통한 최종 검증
[분석/검증-3] BitNet.cpp ARM 커널 재작성 : 스칼라 폴백구현을 통한 최종 검증
1. 개요 및 이전 상황 요약https://uno-kim.tistory.com/458 [분석/검증-2] BitNet.cpp 텐서 연산 붕괴 현상 분석 : ARM 아키텍처 점곱 가속기의 하드웨어 결함 교본 테스트의 목적은 Exynos 1380 프로세서가 지원하
uno-kim.tistory.com
'AI Project > Edge AI Agent - LLM(연구,분석,검증)' 카테고리의 다른 글
| [실전/도전-2] BitNet.cpp 병렬 연산(1xN, Nx1) NEON 커널 수정: 엑시노스 풀 스레드 봉인 해제 (0) | 2026.04.26 |
|---|---|
| [실전/도전-1] BitNet.cpp의 x86 편향성 수정: 모바일 가속기 정상화 (엑시노스도 가능하게 코드수정) (0) | 2026.04.25 |
| [BitNet.Cpp] llama.cpp의 이스터에그 발견과 NEON=1로그의 진실! (0) | 2026.04.25 |
| [분석/검증-3] BitNet.cpp ARM 커널 재작성 : 스칼라 폴백구현을 통한 최종 검증 (0) | 2026.04.25 |
| [분석/검증-2] BitNet.cpp 텐서 연산 붕괴 현상 분석 : ARM 아키텍처 점곱 가속기의 하드웨어 결함 교차 검증 (1) | 2026.04.24 |
댓글