- IBM의 Granite Switch 4.1 8B(2026-10-14 공개, 10-27에 4.1.1로 업데이트, Apache-2.0)는 하나의 모델에 LoRA 어댑터를 내장하고, 채팅 템플릿 인수를 통해 사용 목적을 달리할 수 있는 모델입니다. Apple M3 / 24GB Mac에서 transformers를 사용하여 구동했습니다.
일본어 문의 8건의 창구 분류(decision)와 일본어 요청 6건의 유해 판정(guardian-core)을 각각 1회씩 시도했습니다. 기대했던 6건씩은 모두 기대대로 작동했습니다.
어댑터가 없어도 분류(decision) 6건은 기대대로였으나, 확률이 거의 1.000에 치우쳤습니다. decision에서는 망설이는 2건 중 1건에서 확률이 분리되었습니다. MPS 메모리는 17.2GiB를 사용했고, 채팅 속도는 느렸습니다. 건수가 적기 때문에 사용할 때는 자신의 데이터로 반드시 확인해야 합니다.
Granite Switch는 IBM이 공개한 모델 시리즈입니다. 하나의 베이스 모델에 역할이 다른 LoRA 어댑터(모델 본체는 변경하지 않고, 약간의 추가 가중치로 특정 작업을 위해 조정하는 메커니즘)를 내장하여 하나의 체크포인트로 통합했습니다(GitHub).
이번에는 granite-switch-4.1-8b를 사용해 보았습니다. 모델 카드에 따르면 내용은 다음과 같습니다.
| 항목 | 내용 |
|---|
| 공개일 | 2026-10-14 (4.1), 2026-10-27 (4.1.1) |
| ... | decision (선택지 확률 반환), guardian-core (유해 여부 판정) |
| 음성 | 음성 인식 모델 Granite Speech 5.0 (470M)을 내장. 일본어를 포함한 7개 언어 |
| 라이선스 | Apache-2.0 |
| 구동 방식 | Hugging Face Transformers, vLLM |
어댑터는 aLoRA(Activated LoRA)라는 방식을 사용합니다. 대화 도중에 제어용 토큰(<|decision|> 등)이 나타나는 시점부터만 어댑터를 활성화합니다. 그 이전 부분은 베이스 모델의 계산 결과(KV 캐시)를 그대로 재사용할 수 있습니다(GitHub). 호출하는 쪽에서는 채팅 템플릿에 adapter_name을 전달하기만 하면 됩니다.
'하나의 모델을 로드한 상태에서, 채팅/분류/유해 판정을 전환할 수 있는지', 그리고 '어댑터를 사용했을 때 결과가 어떻게 달라지는지'를 일본어로 확인했습니다.
참고로, 음성 입력은 이번에는 시도하지 않았습니다. granite-switch 0.1.1 버전의 경우, 음성 인식 처리가 vLLM용 코드(granite_switch/vllm/audio/)에만 있고, Transformers용 코드(granite_switch/hf/)에는 없었기 때문입니다(모델 설정의 asr_device도 기본값인 cuda였습니다). granite-switch의 README에서는 대응하는 vLLM (0.26~0.30) 모두 PyTorch 2.11+ (CUDA 13+)가 필요하다고 되어 있어, 이 Mac 환경에서는 시도하지 않았습니다.
모델을 단 한 번만 로드하고 다음 세 가지를 순차적으로 실행했습니다.
- 일반 채팅 (어댑터 없음): 일본의 사계절을 소개하도록 요청 -
- decision: 일본어 문의 8건을 4개의 창구(A=결제/청구, B=로그인/계정, C=배송/도착, D=기타) 중 어디로 분류할지 선택하게 함. 처음 6건은 기대하는 창구를 정해두고, 나머지 2건은 어느 쪽으로든 가능한 문의로 설정했습니다. 어댑터가 없어도 같은 문구로 시도함 -
- guardian-core: 일본어 요청 6건(유해 3건・무해 3건)이 유해한지 아닌지를 판정하게 함
decision의 읽는 방식은 모델 카드 예시에 맞추었습니다. 답변의 첫 번째 토큰에 대해, 선택지 레이블(A~D)의 로짓(각 토큰이 나올 확률을 나타내는 수치)만 추출하여 softmax를 통해 확률로 만듭니다. guardian-core는 {"score": "yes"} 또는 {"score": "no"} 형태의 JSON을 반환하므로, 이를 읽어들입니다. 판정 지시문은 모델 카드 예시를 그대로 사용했습니다.
생성은 모두 탐욕법(do_sample=False)으로, 각 1회씩 진행했습니다.
- OS: macOS 27.2 (Apple M3 / 24GB)
- Python: 3.12.15
- 주요 라이브러리: granite-switch==0.1.1, torch==2.15.0, transformers==5.17.0
- 모델:
ibm-granite/granite-switch-4.1-8b
(revision fb4aa7877e13e5fe09ca328713dc1db72a3f93ce.
2026-11-05 시점의 main에서, 4.1.1), bfloat16, MPS (Mac의 GPU) - 실행일: 2026-11-05
모델 카드에는 4.1.1에 granite-switch-4.1.1-8b라는 태그가 있다고 적혀 있습니다. 하지만 2026-11-05에 Hugging Face API로 확인했을 때는, 태그가 granite-switch-4.1-8b (4.1)만 있었습니다. 그래서 main의 커밋을 직접 지정했습니다.
cd code
uv venv --python 3.12 .venv
uv pip install --python .venv -r requirements.txt
...
API 키는 사용하지 않았습니다.
main.py의 전체 내용입니다. 어댑터의 사용 구분은 apply_chat_template()에 adapter_name을 전달하는지 여부뿐입니다.
"""Granite Switch 4.1 8B를 Mac (MPS)에서 구동하여, 하나의 모델로 3가지 용도를 전환합니다.
1. 일반 채팅 (어댑터 없음)
2. decision 어댑터: 일본어 문의를 어떤 창구에 할당할지 선택합니다 (선택지 확률을 읽음)
...
"""
outputs/run.log입니다. 모델 로딩 진행 표시줄의 줄은 생략했습니다.
# run at: 2026-11-05 09:50:17 JST
Python 3.12.15 / Darwin arm64
torch 2.15.0 / transformers 5.17.0
...
모델을 한 번 로드한 상태로, 채팅(chat), decision, guardian-core를 순차적으로 사용할 수 있었습니다. 전환할 때마다 다시 로드할 필요가 없었습니다. MPS에 할당된 메모리는 처음과 마지막 모두 17.2GiB였습니다.
기대했던 6건은 decision 어댑터 유무와 관계없이 6/6으로 기대대로 작동했습니다. 달랐던 것은 확률 분포입니다.
| 문의 | decision 있음 | 어댑터 없음 |
|---|
| 신용카드를 변경하고 싶은데, 결제 방법 변경 화면을 찾을 수 없다 (기대 A) | A=0.816, B=0.125 | A=0.953, B=0.047 |
| ... | | |
어댑터가 없을 때는 대부분 1.000이거나 그에 가까운 값이었습니다. decision을 사용했을 때는 전체적으로 확률이 약간 분산되었습니다. 망설이는 2건 중 '고장났으니 환불' 건은 결제(A)・기타(D)・배송(C)으로 크게 나뉘었으며, 어댑터가 없을 때와는 1위도 달랐습니다. 나머지 1건의 '로그인할 수 없어 청구서를 볼 수 없다'는 B=0.899 쪽으로 기울었습니다.
모델 카드에는 decision의 확률은 "학습하지 않은 분야에서는 판단 참고용 사전 예상치(prior)로 취급하고, 인증된 분류로는 다루지 않는다"고 쓰여 있습니다. 이번 8건만으로는 어느 쪽의 확률이 맞다고 단정하기 어렵습니다. 확률을 보고 '자신감이 없을 때는 사람에게 넘긴다'와 같은 용도로 사용한다면, 분산된 확률 쪽이 더 다루기 쉬울 가능성이 있습니다. 이는 추측이며, 확인하지는 않았습니다.
유해한 요청 문구는 판정 입력으로만 사용했습니다 (guardian-core는 yes / no만 반환합니다). 유해한 3건(타인의 계정에 대한 부정 로그인, 폭발물 제조 방법, 특정 국가 사람에 대한 편견)은 yes가 나왔고, 무해한 3건은 no가 나왔습니다. '자신의 이메일 계정을 안전하게 지키는 요령'이나 '비밀번호를 잊었을 때'처럼 유해한 요청과 유사한 단어를 포함하는 무해한 요청도 no였습니다. 판정 지시문은 영어 그대로였지만, 이번 일본어 6건에서는 기대대로 작동했습니다.
| 처리 | 시간 (이번 실행) |
|---|
| 모델 로드 | 15.5초 (다운로드 완료 상태에서) |
| ... | |
| 채팅은 매우 느려서, 약 150자 답변에 112.4초가 걸렸습니다. MPS에 확보된 메모리는 17.2GiB였지만, 24GB Mac에서는 메모리 여유 공간이 부족합니다. 속도가 느린 주된 원인은 메모리 부족으로 보이지만, 확실하게는 확인하지 못했습니다. | |
가상 환경을 재구축하고 동일한 run.sh를 다시 실행했습니다(outputs/rerun.log). 채팅 답변문, decision의 확률, guardian-core의 판정은 모두 첫 번째와 같았습니다 (탐욕법(Greedy approach)이므로 같은 환경이라면 같을 것이라 생각됩니다). 달라진 것은 시간뿐입니다. 채팅은 103.7초였으나, decision (어댑터 유/무)는 건당 1.29~3.86초, guardian-core는 최대 23.85초로, 첫 번째 실행보다 편차가 커졌습니다. 속도는 실행할 때마다 크게 변하므로, 이번 수치는 어디까지나 참고치입니다.
-
Granite Switch 4.1 8B 모델은 Apple M3 / 24GB Mac에서도 transformers를 통해 구동되었습니다. 모델을 한 번 로드해 둔 상태에서 adapter_name만 변경하는 것만으로 채팅, decision, guardian-core 기능을 전환할 수 있었습니다. 이번 각 1회 검증에서는 기대 판정 6건과 유해 판정 6건 모두 예상대로였습니다. decision 어댑터의 경우, 망설이는 2건 중 1건에서 확률이 A/D/C로 분기되었습니다. 어댑터가 없는 경우에는 거의 1.000에 치우쳤습니다.
-
한편, MPS에 17.2GiB 메모리를 확보하여 채팅 답변에 약 150자가 112초가 걸렸습니다. 건수 자체가 적기 때문에, 실제로 사용할 때는 자신의 환경과 데이터로 정확도와 속도를 확인해 볼 필요가 있습니다.
-
ibm-granite/granite-switch-4.1-8b — IBM Granite (Hugging Face), 2026-10-14 (4.1) / 2026-10-27 (4.1.1)
-
BUILD.md (granite-switch-4.1-8b) — IBM Granite (Hugging Face)
-
generative-computing/granite-switch — IBM Research (GitHub)
-
granite-switch (PyPI) — PyPI