uvx whichllm@latest)로 추천을 받고, whichllm run으로 바로 다운로드+채팅까지 갑니다. (Andyyyy64/whichllm · Python 3.11+ · MIT · 최신 버전은 PyPI 참조 · PyPI·Homebrew 배포)"내 컴퓨터 사양을 스스로 읽어내고, 그 위에서 실제로 잘 돌면서 똑똑하기까지 한 오픈소스 LLM을 골라 명령어 한 줄로 띄워 주는 도구"입니다. 로컬에서 LLM을 돌리고 싶을 때 가장 막막한 두 질문 — "내 GPU로 어떤 모델이 돌아가지?"와 "그중 뭐가 제일 똑똑하지?" — 에 동시에 답합니다.
이름 그대로 which LLM?(어떤 LLM?)입니다. HuggingFace에 수만 개 모델이 있지만, 정작 "내 RTX 4060 8GB로 진짜 돌아가는 것 중 제일 나은 게 뭐냐"를 한 번에 알려 주는 도구는 드물었습니다. whichllm은 하드웨어 감지 + VRAM 계산 + 속도 추정 + 실제 벤치마크를 결합해 순위표를 뽑아 줍니다. 라이선스는 MIT, 2026년에 등장해 TrendShift 일간 2위에 올랐습니다.
보통 "제일 큰 모델 = 제일 좋은 모델"이라고 생각하기 쉽습니다. 하지만 70B 모델을 8GB GPU에 욱여넣으면 거북이처럼 느리거나 아예 안 켜집니다. 큰 냄비를 작은 주방에 넣는 격이죠.
whichllm은 먼저 주방(하드웨어)의 크기를 자로 잽니다. 그다음 그 주방에 실제로 들어가는 요리(모델)들만 추려, 그중 손님 평점(벤치마크)이 가장 높은 것을 추천합니다. "들어가냐"와 "맛있냐"를 동시에 만족시키는 한 그릇을 골라 주는 셈입니다.
llama.cpp·Ollama·vLLM 같은 엔진으로 띄운다.Q4_K_M·Q5_K_M 같은 표기가 압축 단계다. GGUF는 llama.cpp가 쓰는 양자화 모델 파일 포맷. whichllm은 양자화 단계별로 따로 순위를 매긴다.2026년 들어 로컬 LLM 붐이 거셉니다. 통합 메모리를 가진 Apple Silicon(M4)·AMD Strix Halo·NVIDIA DGX Spark 같은 "AI PC"가 쏟아지고, 프라이버시·무과금을 이유로 모델을 직접 돌리려는 사람이 급증했습니다. 그런데 막상 시작하려면 "내 사양에 뭐가 맞지?"에서 막힙니다. whichllm은 정확히 이 첫 관문을 명령어 한 줄로 뚫어 줍니다.
| 항목 | "VRAM 계산기" 류 | Ollama 모델 목록 | whichllm |
|---|---|---|---|
| 하드웨어 자동 감지 | ✕ (수동 입력) | 일부 | ○ (NVIDIA·AMD·Intel·Apple·CPU) |
| "들어가냐" 판정 | ○ (대략) | △ | ○ (KV캐시·MoE·오프로딩까지 정밀) |
| "똑똑하냐" 순위 | ✕ | ✕ (인기순) | ○ (6종 벤치마크 병합) |
| 최신성 반영 | ✕ | △ | ○ (세대별 recency 디케이) |
| 속도(tok/s) 추정 | 드묾 | ✕ | ○ (대역폭 기반 + 신뢰도) |
| 바로 실행 | ✕ | ○ (ollama run) | ○ (whichllm run, 격리 env) |
| GPU 시뮬레이션 | 드묾 | ✕ | ○ (--gpu "RTX 5090" 구매 전 비교) |
대부분의 도구는 "내 VRAM에 들어가는 가장 큰 모델"을 추천합니다. whichllm은 다릅니다. LiveBench·Artificial Analysis Index·Aider(코딩)·Chatbot Arena ELO·Open LLM Leaderboard·비전 벤치마크 6종을 동시에 가져와 병합하고, 그 점수로 "들어가는 것 중 제일 똑똑한 것"을 고릅니다. 32B 옛 모델보다 점수 높은 14B 최신 모델을 위로 올려 줍니다.
오래된 벤치마크(Open LLM Leaderboard는 2025-06 동결)는 옛 모델 점수가 높게 남아 있습니다. whichllm은 최신 소스(LiveBench·AA)가 있으면 그것으로 덮어쓰고, 옛 소스에만 있는 모델은 "세대가 하나 오래될 때마다 12%씩 깎는"(1.0 − 0.12 × 세대차, 하한 0.55) 계보(lineage) 디케이를 적용합니다. Qwen2.5가 Qwen3을 못 이기게, Llama-3.1이 Llama-3.3을 못 이기게 만드는 장치입니다.
단순히 "파라미터 × 바이트"가 아니라, KV 캐시(컨텍스트 길이에 비례)·GQA·MoE(전문가 혼합)의 활성 파라미터·통합메모리 vs PCIe 오프로딩까지 구분해 계산합니다. 그래서 30B MoE 모델은 102 tok/s, 32B 밀집(dense) 모델은 31 tok/s처럼 현실적인 속도 차이를 보여 줍니다. 추정에는 신뢰도(high/medium/low)와 속도 범위까지 붙습니다.
다른 도구가 "이 옷이 너한테 맞아?"만 답한다면, whichllm은 "맞으면서 가장 잘 어울리는 옷"을 골라 준다. 핏(하드웨어 적합)과 스타일(벤치마크 품질)을 동시에 본다는 게 차이다.
whichllm은 화려한 풀스택이 아니라, 잘 설계된 단일 파이썬 CLI입니다. 약 8,160줄의 소스와 214개의 테스트 함수로 이뤄져, "작지만 단단한" 도구의 좋은 본보기입니다. 핵심은 무거운 ML 라이브러리(torch·transformers)를 평소엔 안 깔고, 실제로 모델을 돌릴 때만 격리 환경에 임시 설치한다는 점입니다.
| 항목 | 내용 |
|---|---|
| 언어 | Python 3.11+ (3.11 / 3.12 / 3.13 지원, OS 무관) |
| CLI 프레임워크 | typer — 타입힌트 기반 CLI. 엔트리포인트 whichllm = "whichllm.cli:app" |
| 출력 | rich — 터미널 컬러 표/마커 렌더링 |
| 빌드 백엔드 | hatchling (src-layout), 의존성 관리 uv + uv.lock |
| 배포 | PyPI(pip install whichllm), Homebrew tap, uvx 제로셋업 실행 |
| 패키지 | 역할 |
|---|---|
| typer | CLI 명령·옵션 정의 |
| rich | 컬러 표·마커 출력 |
| httpx | HuggingFace·벤치마크 소스를 비동기 동시 조회 |
| psutil | RAM·CPU·디스크 용량 감지 |
| dbgpu[fuzz] | TechPowerUp 기반 2,000+ GPU 스펙 DB — --gpu 시뮬레이션·퍼지 매칭 |
| nvidia-ml-py | NVML로 NVIDIA GPU 정밀 감지 |
torch·transformers·llama-cpp-python·autoawq 같은 거대한 패키지는 핵심 의존성이 아니다. 추천을 보여 줄 때는 필요 없고, whichllm run으로 실제 채팅할 때만 uv run --with ...로 격리 환경에 임시 설치한다. 덕분에 도구 자체는 가볍게 설치되고 즉시 뜬다.
uvx whichllm@latest는 설치 없이 도구를 일회성 실행하고, uv run --with <pkg>는 그때그때 임시 가상환경에 의존성을 넣어 스크립트를 돌린다. whichllm의 "한 줄 실행"과 "격리 실행"이 모두 uv 위에서 동작한다.whichllm의 진짜 배울 점은 "파이프라인 설계"입니다. 한 번의 명령이 하드웨어 감지 → 모델 목록 → 벤치마크 → 그룹화 → 순위화 → 출력이라는 명확한 단계를 거치고, 각 단계가 hardware/ · models/ · engine/ · output/ 폴더로 깔끔히 나뉩니다. 도메인 로직을 어떻게 모듈로 쪼개는지 보여 주는 교본입니다.
하드웨어 감지의 각 모듈(NVIDIA·AMD·Intel·Apple·Windows)은 실패하면 예외를 던지지 않고 빈 값을 반환합니다. nvidia-smi가 없으면 NVML로, 그것도 안 되면 다른 경로로 폴백합니다. 한 벤더 감지가 깨져도 전체 도구는 계속 돕니다. "부분 실패를 견디는" 견고함의 좋은 예입니다.
건강검진에서 한 기계가 고장 나도 검진 전체가 중단되지 않는 것과 같다. 혈압계가 멈추면 "혈압: 측정 불가"로 넘어가고 나머지 검사는 계속된다. whichllm의 감지기도 한 벤더가 실패하면 그 칸만 비우고 진행한다.
벤치마크 소스를 "오래돼 동결된 것(Frozen)"과 "계속 갱신되는 것(Current)"으로 나눕니다. combined = frozen ∪ current로 합치되 같은 모델은 current가 frozen을 덮어씁니다. 그래서 2024년 모델이 옛 리더보드에서 받은 높은 점수가, 최신 소스에서는 그저 중위권으로 정정됩니다.
| 계층 | 소스 | 성격 |
|---|---|---|
| Frozen | Open LLM Leaderboard v2(2025-06 동결), Chatbot Arena ELO(2025-07 동결) | 옛 신호 |
| Current | LiveBench, Artificial Analysis Index(~주간), Aider polyglot(코딩), Vision 인덱스 | 최신 신호 |
BENCHMARK_SNAPSHOT = "2026-05"모든 순위표 아래에 기준 스냅샷 날짜가 찍힌다. 라이브 스크랩이 안 되면 내장된 폴백 데이터를 쓰는데, 이때도 "언제 기준 데이터인지"가 보여 추천이 낡았는지 사용자가 즉시 알 수 있다. 벤치마크 도구가 갖춰야 할 투명성의 모범이다.
모든 점수를 같은 무게로 믿지 않습니다. 모델 ID가 정확히 일치하는 direct부터, 변형 매칭(variant), 베이스 모델 추론(base_model), 크기 보간(line_interp), 업로더 자가보고(self_reported)까지 5단계로 신뢰도를 차등합니다. 출처 가중치는 direct 0.62 → self_reported 0.30으로 떨어집니다. 또 파라미터가 가족 평균의 2배 이상 벗어나면 점수 상속을 거부해, 이름만 같은 파생 포크(abliterated·draft)가 점수를 훔치는 걸 막습니다.
full_gpu(전부 GPU) → partial_offload(일부 CPU) → cpu_only → 실행불가로 판정한다. 분리형 GPU의 부분 오프로딩은 PCIe 병목으로 속도가 ×0.45로 떨어지지만, 통합메모리(Apple·APU)는 병목이 없어 ×0.85만 적용한다.폴더 이름이 곧 파이프라인 단계입니다. hardware → models → engine → output 순서로 데이터가 흐릅니다. 특히 data/가 따로 있는 게 핵심 인사이트입니다. GPU 스펙·모델 세대 같은 "자주 바뀌는 지식"을 로직(engine/)에서 분리해 둬서, 새 GPU나 새 모델 세대가 나와도 데이터 파일만 고치면 됩니다.
네트워크가 막히면 whichllm은 내장된 폴백 데이터(AA_INDEX_FALLBACK_2026_05_14, 내장 LiveBench CSV 등)를 쓴다. 즉 결과가 항상 "지금 이 순간"의 라이브 점수가 아닐 수 있다. 그래서 스냅샷 날짜를 꼭 확인해야 하고, 최신 점수가 필요하면 --refresh로 캐시를 무시하고 다시 받아야 한다.
NVIDIA(NVML/nvidia-smi)·AMD(rocm-smi/lspci)·Intel(sysfs)·Apple(system_profiler)·Windows(WMI/PowerShell)를 한 인터페이스로 추상화하는 법을 hardware/에서 배웁니다. 실습: psutil과 nvidia-smi 파싱만으로 "내 GPU VRAM·CPU 코어·RAM"을 출력하는 미니 감지기를 직접 만들어 보기.
벤치마크 6종을 httpx.AsyncClient로 동시에 가져오되, 하나가 실패해도 전체가 안 죽게 처리하는 패턴이 models/benchmark.py에 있습니다. 실습: asyncio.gather(..., return_exceptions=True)로 여러 API를 병렬 호출하고 실패를 건너뛰는 수집기 작성하기.
ranker.py의 품질 점수 공식은 "여러 불완전한 신호를 가중 합산해 하나의 순위로 만드는" 의사결정 엔진의 좋은 예입니다. 실습: 벤치마크·크기·양자화 손실·속도를 입력받아 0~100 점수를 내는 단순화 버전을 파이썬으로 재현해 보기.
모델 목록은 6시간, 벤치마크는 24시간 캐시(~/.cache/whichllm/)합니다. "얼마나 자주 바뀌는가"에 따라 TTL을 다르게 주는 설계를 models/cache.py에서 보세요. 실습: JSON 파일 기반 TTL 캐시 데코레이터를 만들어 API 호출을 줄이기.
--gpu·--cpu-only·--profile·--evidence·--json 등 풍부한 옵션과 plan·upgrade·run 같은 서브커맨드를 Typer로 구성하는 법을 cli.py에서 배웁니다. 실습: Typer로 옵션 3개 + 서브커맨드 2개짜리 CLI를 만들고 --json 출력 모드를 붙이기.
8,160줄 소스에 214개 테스트라는 비율이 인상적입니다. 하드웨어별 감지, 양자화, VRAM, 회귀(regression) 테스트가 분리돼 있습니다. 실습: 점수 함수에 대한 단위 테스트와 "예전 버그가 다시 안 생기게" 하는 회귀 테스트를 직접 작성해 보기.
| 항목 | 요구사항 |
|---|---|
| Python | 3.11 이상 (3.11 / 3.12 / 3.13) |
| uv | 권장 — uvx 제로셋업 실행 및 run 명령의 격리 실행에 필요 |
| OS | Linux · macOS(Asahi 포함) · Windows 모두 지원 |
| 네트워크 | 최신 모델/벤치마크 수집에 필요(없으면 내장 폴백 데이터 사용) |
| 디스크 캐시 | ~/.cache/whichllm/ — models.json(6h), benchmark.json(24h) |
| GPU 드라이버 | 감지 정밀도를 위해 NVIDIA는 NVML/드라이버, AMD는 ROCm 권장(없어도 폴백 동작) |
| 명령 | 하는 일 |
|---|---|
| whichllm | 내 컴퓨터에 맞는 최적 모델 순위 출력 |
| whichllm --gpu "RTX 5090" | 그 GPU를 샀다고 가정하고 시뮬레이션 (구매 전 비교) |
| whichllm --top 20 --quant Q4_K_M --min-speed 30 | Q4_K_M·30tok/s 이상만 상위 20개 |
| whichllm --profile coding | 코딩(또는 vision·math·general) 용도에 맞춰 순위 |
| whichllm plan "llama 3 70b" | 역방향 — 이 모델 돌리려면 어떤 GPU가 필요한지 |
| whichllm upgrade "RTX 4090" "RTX 5090" "H100" | 여러 GPU 후보를 나란히 비교 |
| whichllm run "qwen 2.5 1.5b gguf" | 다운로드 + 즉석 채팅 (격리 env 자동 구성) |
| whichllm snippet "qwen 7b" | 실행하지 않고 바로 쓸 수 있는 파이썬 코드만 출력 |
| whichllm hardware | 감지된 내 하드웨어 정보만 표시 |
uvx whichllm@latest를 실행해 내 하드웨어에 맞는 순위표를 본다. whichllm hardware로 감지 결과를 확인하고, 1위 모델의 점수 옆 마커(~·!sr·?)가 무엇을 뜻하는지 docs/scoring.md와 대조하기.
whichllm --gpu "RTX 4060" --vram 8와 --gpu "RTX 5090"의 결과를 비교해, VRAM이 늘면 어떤 모델이 새로 "들어가게" 되는지 관찰한다. upgrade로 두 GPU를 한 번에 비교해 보기.
whichllm run "qwen 2.5 1.5b gguf"로 작은 모델을 받아 직접 대화해 본다. whichllm snippet으로 생성되는 파이썬 코드를 읽고, GGUF는 llama-cpp-python, AWQ는 transformers로 의존성이 갈리는 이유를 정리하기.
소스의 engine/vram.py를 읽고 "가중치 + KV캐시(B당 K당 3.5MB) + 활성 + 오버헤드" 공식을 파이썬으로 옮겨, 7B 모델의 8K/32K 컨텍스트 VRAM을 손으로 계산해 본다. 컨텍스트가 길어질수록 얼마나 늘어나는지 그래프로 그리기.
benchmark_sources/의 한 모듈을 본떠, 내가 신뢰하는 새 리더보드를 fetch·정규화하는 소스를 추가한다. Frozen/Current 어디에 둘지, 출처 가중치는 얼마로 줄지 결정하고 테스트까지 작성해 PR 형태로 정리하기.
| 주차 | 학습 주제 | 실천 목표 |
|---|---|---|
| 1주차 | 로컬 LLM 기초 + Ollama | Ollama로 모델 3개 띄워 보고, 양자화 단계별 속도·품질 체감 |
| 2주차 | 양자화 / GGUF | 같은 모델의 Q4/Q5/Q8을 받아 VRAM·tok/s·답변 품질 비교 정리 |
| 3주차 | llama.cpp 내부 | KV 캐시·GQA·컨텍스트 길이가 메모리에 미치는 영향 실험 |
| 4주차 | MoE 아키텍처 | 전체 vs 활성 파라미터 개념 학습, MoE 모델 직접 실행해 속도 확인 |
| 5주차 | 하드웨어 감지 / psutil·NVML | 크로스플랫폼 시스템 정보 수집기 직접 구현 |
| 6주차 | 비동기 파이썬 (asyncio·httpx) | 여러 API를 병렬 수집하고 실패를 견디는 수집기 작성 |
| 7주차 | 벤치마크 리터러시 | LiveBench·Arena·AA Index가 무엇을 측정하는지·한계가 무엇인지 정리 |
| 8주차 | CLI 패키징·배포 | uv/hatchling로 PyPI 배포 가능한 나만의 CLI 도구 완성 |
1.0 − 0.12 × 세대차, 하한 0.55). 동결된 리더보드의 옛 모델이 최신 모델을 부당하게 이기지 못하게 한다.| 링크 | 설명 |
|---|---|
| GitHub 저장소 | 소스 전체. src/whichllm/·docs/·tests/가 핵심 |
| PyPI: whichllm | pip install whichllm 배포 페이지 |
| TrendShift 페이지 | 트렌딩 추이(일간 2위, 2026-06-09) |
| uv 문서 | uvx·uv run 등 whichllm 실행의 기반 도구 |
| llama.cpp | GGUF·양자화·KV 캐시의 원천. 로컬 LLM 엔진의 사실상 표준 |
| LiveBench | 오염 방지·갱신형 벤치마크(Current 소스) |
| Artificial Analysis | 모델 지능·속도·가격 비교(AA Index, Current 소스) |
| HuggingFace Models | whichllm이 모델 목록을 가져오는 곳 |
| Typer | whichllm CLI를 떠받치는 파이썬 CLI 프레임워크 |