# 문제 해결

대부분의 qb Compiler 문제는 어느 단계에서 실패했는지 확인하면 좁힐 수 있습니다.

```text
원본 모델 -> parse -> MBLT -> quantize -> MXQ
```

원본 모델이 MBLT로 변환되지 않으면 `parse`를 확인합니다. 연산자 지원 여부나 그래프 경계가 불명확하면 MBLT를 Netron으로 엽니다. 캘리브레이션, 양자화, MXQ 생성 문제가 의심되면 `quantize`를 확인합니다.

## 설치 문제

대표 증상은 `qbcompiler: command not found`, Python import 실패, CLI 시작 시 공유 라이브러리 오류입니다.

```bash
python -m pip show qbcompiler
python -c "import qbcompiler; print(qbcompiler.__file__)"
python -m qbcompiler --help
```

qb Compiler가 설치된 Python 환경을 사용해야 합니다. 여러 가상 환경, Conda 환경, 컨테이너가 있다면 `python`, `pip`, `qbcompiler`가 같은 환경을 가리키는지 확인합니다. 공유 라이브러리 오류가 나면 설치 가이드와 `LD_LIBRARY_PATH` 또는 컨테이너 이미지의 런타임 라이브러리 구성을 확인합니다.

## target device 오류

유효한 target device 문자열은 다음과 같습니다.

- `regulus-ra`
- `aries-rb`
- `regulus-rb`

CLI 옵션과 컴파일 설정에서 정확한 target device 문자열을 사용합니다. 값으로 ARIES나 REGULUS 같은 NPU 칩 이름을 사용하지 않습니다. MXQ는 런타임 배포 환경이 기대하는 target device와 같은 값으로 컴파일되어야 합니다.

## 모델 parse 실패

`parse` 실패는 보통 원본 모델을 로드할 수 없거나, 입력 형상 추론에 실패했거나, 내보낸 그래프에 지원되지 않는 프레임워크 구조가 포함된 경우입니다.

확인:

- `backend`가 원본 모델과 맞는지 확인합니다. 지원 값은 `onnx`, `tf`, `tflite`, `torchscript`, `torch`입니다.
- 고정 입력 형상으로 모델을 다시 내보냅니다.
- PyTorch 모델은 내보내기 전에 eval mode로 전환합니다.
- 학습 전용 노드, 무작위 분기, 디버그 출력, Python 측 제어 흐름을 제거합니다.
- ONNX 모델은 `onnxsim` 같은 ONNX 최적화 라이브러리로 정리한 파일을 사용하면 더 안정적으로 파싱됩니다.
- HuggingFace 모델은 모델 로더, 토크나이저, `trust_remote_code` 설정이 원본 저장소와 맞는지 확인합니다.
- LLM 및 HuggingFace 모델은 qb docker에서 사용하는 `transformers` 버전에 맞추거나, 모델 파싱에 사용하는 스크립트에 명시된 `transformers` 버전에 맞춰 환경을 구성합니다.

가능하면 `parse`를 분리 실행하고 생성된 MBLT를 Netron으로 엽니다. `parse`가 MBLT를 만들지 못하면 문제는 모델 로딩, 프레임워크 변환, NPU 컴파일 전 그래프 정규화 단계에 있습니다.

## 지원되지 않는 레이어

Netron에서는 지원되는 레이어가 파란색, 지원되지 않는 레이어가 검정색으로 표시됩니다. `compile`이 지원되지 않는 연산자를 보고하거나 NPU 본문(`NPU body`)이 예상보다 작으면, 먼저 해당 레이어가 반드시 컴파일된 NPU 본문에 있어야 하는지 판단합니다.

그래프 경계 주변의 지원되지 않는 전처리 또는 후처리는 CPU 오프로딩이나 애플리케이션 쪽 코드로 처리할 수 있습니다. 주요 계산 본문 내부의 지원되지 않는 레이어는 대개 모델 다시 내보내기, 그래프 단순화, 또는 지원되는 동등 연산자 패턴으로 변경해야 합니다.

유용한 조치:

- Netron에서 지원되지 않는 레이어 위치를 찾습니다.
- 해당 레이어가 `CPU head`, `NPU body`, `CPU tail` 중 어디에 있는지 확인합니다.
- 사용자 정의 연산자를 내보내기 전에 표준 ONNX 또는 프레임워크 연산자로 바꿉니다.
- 배포 형상이 고정되어 있다면 동적 형상 로직을 상수로 고정합니다.

## 캘리브레이션 데이터 오류

캘리브레이션 오류는 보통 파일 로딩 실패, 입력 개수 또는 텐서 이름 불일치, 양자화 중 형상/데이터 타입 불일치로 나타납니다.

확인:

- 각 캘리브레이션 샘플은 컴파일된 모델의 입력 명세와 일치해야 합니다.
- 다중 입력 모델은 모든 샘플마다 입력별 텐서가 하나씩 필요합니다.
- 파일 이름과 디렉터리 레이아웃은 캘리브레이션 로더 규칙과 일치해야 합니다.
- 데이터 타입은 예상 입력 경로와 맞아야 합니다. 예를 들어 정규화된 텐서는 `float32`, 원본 입력 흐름은 `uint8`일 수 있습니다.
- CPU 오프로딩을 쓰면 캘리브레이션 형상은 원본 모델 입력과 일치해야 합니다. NPU 본문 전용 컴파일에서는 NPU 본문 입력과 일치해야 합니다.
- 전처리는 런타임 추론과 같아야 합니다. 채널 순서, 레이아웃, 스케일링, 정규화, 크기 변경, 자르기, letterbox, 패딩, 토큰화, 마스크를 확인합니다.

먼저 작은 캘리브레이션 데이터셋으로 형식을 검증한 뒤 샘플 수를 늘립니다.

## 양자화 정확도 저하

부동소수점 MBLT 출력은 괜찮지만 MXQ 출력이 좋지 않거나, 특정 레이어 이후 오차가 크게 증가하거나, 캘리브레이션 샘플 선택에 따라 정확도가 민감하게 변하면 양자화 문제일 가능성이 큽니다.

조치:

- 양자화 튜닝 전에 파싱, 전처리, 캘리브레이션 형상이 맞는지 확인합니다.
- 캘리브레이션 샘플 수를 늘리고 더 대표성 있는 샘플을 사용합니다.
- 원본 파이프라인과 캘리브레이션 생성기에서 나온 단일 전처리 텐서를 비교합니다.
- 수동 양자화 변경 전에 작업 프리셋을 먼저 사용합니다.
- 사용 가능한 경우 합성곱이 많은 모델에는 채널별 가중치 양자화를 사용합니다.
- 민감한 출력 레이어 또는 작업 head는 지원되는 범위에서 더 안전한 양자화 설정으로 유지합니다.
- 중간 출력을 검증해 오차가 처음 크게 증가하는 레이어를 찾습니다.

YOLO는 letterbox 크기, 패딩 값, 스케일 복원을 확인합니다. LLM은 토크나이저, 임베딩 가중치, 시퀀스 자르기, 어텐션 마스크 생성을 확인한 뒤 양자화 설정을 조정합니다.

양자화 정확도 저하의 체계적인 진단 및 복구 방법과 하위 설정 튜닝 순서, 추천 설정 예시는 [모델 양자화 — 정확도 저하 대응](model_quantization.md#accuracy-degradation-response)을 참고합니다.

## MXQ 생성 실패

MXQ 생성 실패는 보통 캘리브레이션이 시작된 뒤 실패하거나, 메모리가 부족하거나, `quantize`가 MXQ를 쓰지 못하는 형태로 나타납니다.

확인:

- MBLT가 같은 target device로 생성되었는지 확인합니다.
- 캘리브레이션 데이터를 읽을 수 있고 충분한 유효 샘플이 있는지 확인합니다.
- 메모리 압박을 분리하기 위해 배치 크기, 시퀀스 길이, 캐시 길이, 입력 해상도를 줄입니다.
- LLM은 먼저 작은 `max_sequence_length`와 `max_cache_length`로 시도합니다.
- 출력 경로에 쓰기 권한과 충분한 디스크 공간이 있는지 확인합니다.
- 지원되지 않거나 큰 연산 범위를 만드는 후처리를 불필요하게 NPU 본문에 포함하지 않습니다.

`compile`이 실패하면 흐름을 `parse`와 `quantize`로 나누어 실패 단계를 확인합니다.

## LLM 시퀀스, 캐시, 배치 오류

대표 증상은 어텐션 형상 불일치, KV 캐시 텐서 불일치, 런타임 프롬프트 길이의 컴파일된 한도 초과, 배치 크기 불일치입니다.

확인:

- `max_sequence_length`는 컴파일된 그래프가 사용하는 프롬프트 시퀀스 길이 이상이어야 합니다.
- `max_cache_length`는 의도한 KV 캐시 용량과 일치해야 합니다.
- 배치 크기는 캘리브레이션, 컴파일 설정, 런타임에서 일관되게 고정되어야 합니다.
- 캘리브레이션 임베딩 텐서는 원본 모델 임베딩과 같은 hidden size와 데이터 타입을 사용해야 합니다.
- 동적 RoPE, 동적 마스크, `splitBlocks`, `splitParts` 설정은 모델 아키텍처와 메모리 목표에 맞아야 합니다.

진단할 때는 짧은 시퀀스와 캐시 길이로 먼저 컴파일합니다. 그 경로가 동작하면 한도를 점진적으로 늘리며 컴파일러 메모리 사용량을 확인합니다.

## Netron에서 MBLT가 열리지 않는 경우

임의의 upstream Netron 빌드 대신 Mobilint Netron을 사용합니다.

- 웹 서비스: `http://netron.mobilint.com`
- Windows/Linux 내려받기: `http://dl.mobilint.com`

파일이 현재 컴파일러가 만든 MBLT인지, 실패한 `parse`에서 생긴 일부만 기록된 파일이 아닌지 확인합니다. 그래프가 원본 모델과 다르게 단순화되어 보일 수 있습니다. MBLT는 파싱된 IR이므로 그래프 정규화와 연산자 결합 때문에 시각적 구조가 달라지는 것은 정상일 수 있습니다.
