
【Ollama】 엄청나게 느린 로컬 LLM 처리 속도를 1/10로 단축했지만, 바보 같았다 【이미지 인식】 (Part 2)
요약
Ollama를 사용하여 MacBook 환경에서 로컬 LLM(Qwen)의 이미지 인식 속도를 개선하려는 시도를 다룹니다. 초기 400초가 소요되던 처리 시간을 분석하고, 컨텍스트 길이 설정 등 다양한 시행착오를 통해 성능 저하 원인을 파악하는 과정을 담고 있습니다.
핵심 포인트
- 로컬 LLM의 이미지 인식 처리 속도가 매우 느린 문제 발생
- 모델 로드, 프리필, 디코딩 단계별 성능 분석 수행
- 디코딩 단계에서의 방대한 토큰 출력이 병목 원인으로 추정
- 컨텍스트 길이(num_ctx) 설정 변경을 통한 최적화 시도 및 시행착오
지난 편의 다음 내용입니다.
Part 1은 이쪽으로 → 【Ollama】 MacBook에서 로컬 LLM을 구현하기 【이미지 인식】 (Part 1)
지난 줄거리
「로컬 LLM으로 장표를 읽어보자!」
⬇️
「Ollama는 정말 간편하게 쓸 수 있구나! 만세!!」
⬇️
「어? 엄청나게 느린데...? (1장당 400초)"
시작하며
네, 먼저 결론부터 말씀드리면, 문제의 녀석은 제목 그대로 토벌에 성공했습니다.
...라고는 해도, 파멸적으로 느렸던 읽기 속도가 어떻게든 20~30초 정도로 줄어들었을 뿐입니다.
읽고 계신 분들로부터
「야! 빨리 원인과 상세 내용, 해결책만 내놔!! 나는 도움이 되는 정보만 알고 싶다고!!!"
와 같은 호통이 들려오는 것 같네요.
안심하세요.
아마도 이 글을 보셔도, 도움이 될 만한 기술적인 발견은 없습니다.
그래서 저는 비명을 무시하고 끝까지 끌고 가겠습니다.
그래도 도저히 결론만 알고 싶으신 분은 '끝' 부분만이라도 봐 주세요. 결코 후회하지는 않을 겁니다.
마음을 가다듬고...
자, 로컬 LLM을 엄청나게 느리게 만들었던 요인은 과연 무엇이었을까요?
과언이 아니지만, 그것을 해결하기 위해서는 현대 사회를 살아남기 위해 필요한 인간으로서의 자질이 시험받고 있었습니다. (과언입니다)
문제가 뭐야?
문제에 대해 서두에 얇게 썼지만, 좀 더 구체적으로 써보겠습니다.
그것은, 로컬 LLM(Qwen)으로 읽어서 출력하기까지의 시간이 너무 느리다! 입니다.
얼마나 느리냐고요?
400초 ^ ^
참고로 Gemini의 API를 사용할 때라면 5~6초 정도입니다.
으음, 현재로서는 로컬 LLM은 쓸모가 없네요. 그렇다고는 해도 해결하고 싶습니다...
우선 했던 일
실제로 걸리는 시간에 대해 상세히 조사해 보았습니다.
그렇다고는 해도 어느 범위를 확인해야 하는지 표준을 몰랐기 때문에, 조사하면서 다음 항목들을 조사했습니다.
3가지 포인트로 문제를 나누어 보겠습니다.
모델 로드 시간 -
프리필 (Prefill) (입력 = 이미지 토큰 + 프롬프트 처리) 및 그 입력 토큰 수 -
디코딩 (Decoding) (출력 생성) 및 그 생성 토큰 수 - 각 단계의 토큰/초 (tokens/s)
로그를 확인한 결과를 정리해 보았습니다.
| 단계 | 시간 | 토큰 | 속도 |
|---|---|---|---|
| 모델 로드 | 2.3초 | — | (오차) |
| 프리필 (입력) | 17.1초 | 2,348 | 137 tok/s |
| 디코딩 (출력) | 435.4초 | 9,940 | 22.8 tok/s |
| 합계 | 454.9초 |
...디코딩 처리네.
다만 토큰 처리 속도는 문제가 없어 보입니다. (인간은 평균적으로 초당 5토큰 정도를 인식한다고 합니다.)
문제는 방대한 토큰의 출력 인 것 같다... 는 걸까요?
일단 어떤 영향으로 처리 성능이 나쁜 것이 아니라서 안심입니다. 딱히 「로컬 LLM은 원래 이런 건가...」라고 생각하고 있는 건 아니에요!
악영향을 끼치는 정체는?
먼저 떠오른 것이 「컨텍스트 길이 (Context Length)」입니다. 지난번(Part 1) 마지막에 언급했지만, 장표를 읽는 데 있어서 기본 컨텍스트 길이에서 변경해야만 했습니다.
하지만 확인해 보니, 최소한으로 동작하도록 num_ctx=12288로 설정해 두었습니다. 아무래도 이 방향성은 맞지 않는 것 같습니다...
(심지어 빈 응답(empty response)으로 크래시가 나는 경우도 있어서, 부족한 경우도 있었습니다.)
이쯤에서 저의 LLM 지식이 한계에 도달했기에 AI에게 의지했습니다. 지금 생각하면 이건 좋지 않네요.
일단 비망록 정도로 했던 일을 간단히 정리하겠습니다.
※ 미리 말씀드리자면, 시도한 것들은 모두 실패였습니다.
| 시도 | 실패한 이유 |
|---|---|
| num_ctx를 32768로 확대 | "클수록 안전하다"고 오해. M2 Pro(32GB)에서는 KV 캐시(KV Cache)가 RAM을 압박하여 스왑(Swap) 발생 → 6배 느려짐. 유니파이드 메모리(Unified Memory)에서는 컨텍스트(Context) 과다 설정이 오히려 역효과를 냄 |
| json_schema → json_object | 폭주의 원인은 문법 제약이 아니었으므로 무효. 증상(긴 출력)을 보고 원인을 잘못 파악함 |
| repeat_penalty | 폭주의 정체는 "답변의 반복"이었으므로, 답변 측에 적용되는 페널티는 무관함 |
| max_tokens로 제한 | Ollama는 제한(finish=length) 시 내용을 빈 값으로 반환하는 사양. 상한을 걸수록 "빈 응답"을 양산. 오히려 악화 |
| JSON 구제 (도중에 끊긴 JSON 복구) | Ollama가 빈 값을 반환하므로 구제할 재료조차 없었음. 대증요법 자체가 성립하지 않음 |
알다시피, 모두 임시방편적인 대응입니다.
자주 쓰이는 말이지만, AI는 결국 사용하는 사람의 능력에 달려 있다는 뜻이겠네요.
네, 이 시점에서 이미 제 마음속에는 포기 분위기가 감돌고 있었습니다. 장송곡이 흐르고 있었죠.
한 줄기 희망의 빛
하루 정도 방치해 두고 느긋하게 시간을 보냈습니다.
그러다 로컬 LLM(Local LLM)으로 놀았던 것이 생각났습니다.
"그러고 보니 ollama run <모델명>
명령어로 놀았을 때도 왠지 느렸었지..."
"왠지 답변을 생성하기 전에, 후보 문장이 몇 번이고 출력되었던 것 같은데......??"
..앗! (・◇・)
이거잖아! 혹시 사고 모드(Thinking Mode)?
제 몸에 전류가 흘렀습니다.
해결로
먼저 streaming / think:false 플래그를
만져보았습니다. 아니, AI에게 만져달라고 했습니다. Ollama에서는 이것으로 사고 모드를 스위치할 수 있는 모양입니다.
하지만 이것으로는 잘 되지 않았습니다. 아무래도 이미지 인식 모델은 스위치할 수 없도록 되어 있다고 합니다.
그래서 다시 한번 Ollama의 모델 카탈로그를 제대로 살펴보고, 해당되는 모델이 없는지 찾아보았습니다.
"Qwen2-vl"을 사용하고 있었기에 다시 확인해 보니...

View...all...? 이런 게 있었나?
조심스럽게 눌러보니,

있잖아ーーーーー!!!!!!!!!!
thinking
이라는 게 있고, 그것이 사고 모드 모델이라면, 혹시 instruct
라는 건 사고하지 않는? 모드라는 뜻인가?!
그나저나 그냥 지나칠 뻔했네~~~ ㅎㅎ
모델만 바꿔서 시도해 본 결과,
400초 초과 -> 20~30초
제목 그대로 1/10로 단축되었습니다.
음, 순수하게 기뻐할 수만은 없네요.
끝
LLM은 사고 모드가 있고, 모델에 따라 설정도 변화한다. 음, 오히려 맹점이었네!
네. 결론은 제 머리가 부족했다. 입니다.
자주 언급되는 내용이라 중간에도 말씀드렸지만,
"AI를 활용했을 때의 힘은 본인의 능력에 좌우된다"
그것을 몸소 체험할 수 있었습니다.
그리고 처음에 말했듯이, 도움이 될 만한 기술적인 발견은 없었다고 생각합니다. 힘내세요.
이번에는 초보 중의 초보적인 실수였지만, 경험이나 지식이 없으면 이렇게나 깊은 수렁에 빠지게 되는군요. (어디가 통찰력이라는 거야)
뭐, 하루 만에 끝났으니 다행이라고 합시다.
일단 이 양식 읽기는 일단락된 걸까요?
앞으로는 더 빠르게 하거나 정밀도를 높이고 싶고, 파인튜닝(Fine-tuning)도 도전해 보고 싶네요!
어차피 할 때마다 초보적인 실수가 나올 테니, 굴하지 말고, AI에만 맡기지 말고, 공부 열심히 하자!!
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기