# 모델 파싱

MBLT는 모빌린트의 파싱된 모델 형식입니다. qb Compiler가 원본 모델을 읽어 내부 표현으로 변환한 뒤의 모델 그래프와 가중치를 담습니다. 기본 파이프라인에서 MBLT는 원본 모델과 최종 MXQ 패키지 사이의 중간 산출물입니다.

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

대부분의 사용자는 원본 모델을 바로 MXQ로 컴파일합니다. MBLT를 명시적으로 생성하는 흐름은 파싱된 그래프를 확인하거나, 어떤 레이어가 NPU에서 실행 가능한지 확인하거나, 파싱 문제와 MXQ 생성 문제를 분리해서 볼 때 유용합니다.

## MBLT 생성 방법

원본 모델을 모빌린트 High-level IR인 MBLT로 변환하려면 `mblt_compile` Python API를 사용합니다.

```python
from qbcompiler import mblt_compile

mblt_compile(
    model="resnet50.onnx",
    backend="onnx",
    target_device="aries-rb",
    mblt_save_path="resnet50.mblt",
)
```

`backend` 값은 원본 모델의 프레임워크를 선택합니다. 지원되는 백엔드 이름은 `onnx`, `tf`, `tflite`, `torchscript`, `torch`입니다. HuggingFace transformers 모델은 별도 백엔드가 아니라 `torch` 경로를 사용하며, 필요한 모델, 토크나이저, 입력, LLM 설정은 Python 또는 컴파일 설정에서 제공합니다.

`target_device` 값은 최종 MXQ를 만들 때 사용할 모빌린트 target device 문자열과 맞춰야 합니다. 일반적으로 사용하는 값은 `aries-rb`, `regulus-ra`, `regulus-rb`입니다.

CPU 오프로딩을 사용할 경우, 최종 컴파일과 같은 CPU/NPU 경계로 그래프를 나누기 위해 MBLT 생성 단계에서도 CPU 오프로딩을 활성화합니다.

동일한 작업은 `parse` CLI로도 수행할 수 있습니다. 단, CLI를 통한 방법은 백엔드가 `onnx`일 때만 권장됩니다.

```bash
python -m qbcompiler parse \
  --model resnet50.onnx \
  --backend onnx \
  --target-device aries-rb \
  --output resnet50.mblt
```

CPU 오프로딩을 사용하는 경우:

```bash
python -m qbcompiler parse \
  --model yolov8n.onnx \
  --backend onnx \
  --target-device aries-rb \
  --cpu-offload \
  --config-preset yolo_640 \
  --output yolov8n.mblt
```

## MBLT에서 MXQ 생성 방법

이미 생성된 MBLT를 MXQ로 변환하려면 MBLT 경로를 `model`로 넘기는 `mxq_compile` Python API를 사용합니다.

```python
from qbcompiler import mxq_compile

mxq_compile(
    model="resnet50.mblt",
    calib_data_path="./calibration/resnet50",
    config_preset="classification",
    save_path="resnet50.mxq",
)
```

전체 컴파일에서 사용할 프리셋 또는 컴파일 설정과 같은 계열의 설정을 사용합니다. 이 단계는 캘리브레이션과 양자화만 수행하는 단계가 아니라, target device에서 실행 가능한 MXQ 패키지를 만들기 위한 컴파일 및 machine instruction 바이너리/패키지 생성 작업도 포함합니다.

동일한 작업은 `quantize` CLI로도 수행할 수 있습니다. 단, CLI를 통한 방법은 백엔드가 `onnx`일 때만 권장됩니다.

```bash
python -m qbcompiler quantize \
  --mblt resnet50.mblt \
  --calib-data-path ./calibration/resnet50 \
  --config-preset classification \
  --output resnet50.mxq
```

고급 옵션은 JSON/YAML 설정을 생성하거나 수정한 뒤 `--compile-config`로 전달합니다.

```bash
python -m qbcompiler dump-config \
  --preset yolo_640 \
  --output yolo_640_config.yaml

python -m qbcompiler quantize \
  --mblt yolov8n_body.mblt \
  --calib-data-path ./calibration/yolo \
  --compile-config yolo_640_config.yaml \
  --output yolov8n.mxq
```

## Netron으로 MBLT 열기

Netron은 MBLT 그래프 구조와 NPU 지원 여부를 확인하기 위한 권장 시각화 도구입니다. 캘리브레이션과 MXQ 생성에 시간을 쓰기 전에 레이어 순서, 텐서 흐름, 입출력 형상, CPU/NPU 경계를 확인하는 용도로 사용합니다.

모빌린트는 두 가지 접근 경로를 제공합니다.

- Netron 웹 서비스: [http://netron.mobilint.com](http://netron.mobilint.com)
- Windows/Linux용 내려받기: [http://dl.mobilint.com](http://dl.mobilint.com)

MBLT 확인 순서는 다음과 같습니다.

1. `parse` 또는 `mblt_compile`로 `.mblt`를 생성합니다.
2. Netron을 엽니다.
3. `.mblt` 파일을 로드합니다.
4. 모델 입력부터 모델 출력까지 그래프 흐름을 따라갑니다.

모델에 고객 데이터 또는 비공개 가중치가 포함되어 있다면 웹 서비스에 업로드하지 말고, 필요한 보안 환경에서 내려받기 버전의 Netron을 사용합니다.

## 모델 레이어 구성과 NPU 지원 여부 확인

모빌린트 Netron 보기에서는 레이어 색상이 NPU 지원 여부를 나타냅니다.

| 색상   | 의미                                                                                        |
| ------ | ------------------------------------------------------------------------------------------- |
| 파란색 | 지원되는 레이어입니다. 해당 레이어는 NPU에 할당될 수 있습니다.                             |
| 검정색 | 지원되지 않는 레이어입니다. 해당 레이어는 CPU에서 실행되거나 NPU 본문 밖에서 처리되어야 합니다. |

색상 표시는 첫 번째 지원 여부 확인 단계로 사용합니다. 그 다음 그래프 경계를 확인합니다.

- 완전히 지원되는 모델은 주요 계산 그래프가 입력부터 출력까지 파란색으로 표시되어야 합니다.
- 입력 근처의 지원되지 않는 전처리는 보통 `CPU head`로 나타납니다.
- 가운데의 지원되는 주요 레이어들은 `NPU body`를 구성합니다.
- 출력 근처의 지원되지 않는 후처리는 보통 `CPU tail`로 나타납니다.

이 확인은 크기 변경, 디코딩, NMS, 사용자 정의 텐서 reshape, 작업별 후처리가 내보낸 그래프 안에 포함된 모델에서 특히 중요합니다.

## CPU head, NPU body, CPU tail 구조

CPU 오프로딩을 사용하면 qb Compiler는 하나의 파싱된 모델을 여러 서브그래프로 나눌 수 있습니다.

| 서브그래프 | 의미                                                                                                                   |
| -------- | ---------------------------------------------------------------------------------------------------------------------- |
| CPU head | NPU body 앞에 있으며 NPU에 할당되지 않는 CPU 실행 구간입니다. 전처리 또는 형상 준비가 포함되는 경우가 많습니다.        |
| NPU body | NPU에서 실행 가능한 가장 큰 본문 서브그래프입니다. 핵심 NPU 실행 경로로 컴파일되는 부분입니다.                         |
| CPU tail | NPU body 뒤에 있으며 NPU에 할당되지 않는 CPU 실행 구간입니다. 디코딩, 필터링, 후처리가 포함되는 경우가 많습니다.       |

Netron에서 MBLT를 확인할 때는 `NPU body`가 모델의 계산량이 큰 핵심 구간을 포함하는지 확인합니다. 작은 `CPU head` 또는 `CPU tail`은 허용 가능한 경우가 많지만, `NPU body`가 작다면 모델 구조, 내보내기 옵션, 컴파일 설정을 다시 확인해야 합니다.

## YOLO 등 일부 모델에서 잘린 구간 확인

YOLO 계열 모델은 탐지 head 디코딩 또는 후처리 연산자를 그래프 안에 포함하는 경우가 많고, 이 구간은 NPU 실행에 가장 적합한 영역이 아닐 수 있습니다. 이런 경우 일반적으로 기대하는 구조는 다음과 같습니다.

```text
CPU head가 있으면 CPU head -> NPU body -> CPU tail
```

YOLO와 유사한 탐지 모델에서는 최종 MXQ를 만들기 전에 다음을 확인합니다.

- 백본과 주요 탐지 계산 경로가 파란색이며 `NPU body`에 포함되어 있습니다.
- 검정색의 지원되지 않는 레이어가 전처리, decode, NMS, 기타 CPU 후처리로 예상한 영역에 제한되어 있습니다.
- `NPU body` 출력 텐서가 런타임 또는 애플리케이션 후처리 코드가 기대하는 텐서입니다.

`NPU body`가 너무 일찍 끝나거나, 너무 늦게 시작하거나, 주요 합성곱/어텐션 블록을 제외한다면 원본 모델 내보내기와 컴파일 설정을 다시 확인합니다. YOLO 모델에서는 내보내기 옵션에 따라 디코딩과 후처리가 그래프 안에 포함될지 달라지고, 이 차이가 `CPU tail`과 본문 서브그래프 인터페이스를 직접 바꿉니다.
