8GB GPU 한 대로 Gemma 4 를 진짜 24 시간 돌려본 결과 — 황 (thehwang) 과 두 개 다른 컴퓨터에서 똑같이 재현된 함정 세 가지
한 줄 요약. 다섯 글 전, "오픈 웨이트 작은 모델 (Gemma 4) 이 프론티어 닫힌 모델 (Claude / Gemini 같은 클라우드 모델) 을 대체할 수 있을까" 라는 질문으로 시리즈 시작. 대부분의 일에 답은 yes. 이 마지막 글은 시리즈가 안 다룬 부분 = 실제로 배포해서 돌리는 것 을 다룹니다. RTX 4060 8 기가바이트 그래픽카드에서 작은 모델 3 종 × 컨텍스트 창 크기 3 종에 걸쳐 24 번 실험 = 총 시간 14.7 분. 황 (thehwang) 가 같은 모양의 실험 도구 (harness, 마구 = 실험 자동화 셋업) 를 맥 16 기가바이트에서 돌림. 세 가지 발견이 두 컴퓨터 환경에서 똑같이 재현됨. 한 가지 발견은 입력 자료 모양에 따라 결과 방향이 뒤집힘. 이 모든 걸 감싸는 운영 cron (자동 스케줄) 라인업 = 월 5 달러 이하 + 18 일 동안 24 건 발견 해결.
이 마지막 글이 다루는 것
운영 배포 정리. 단일 소비자용 그래픽카드에서 오픈 웨이트 작은 모델을 4 개월째 돌려본 결과 = 정작 문제 일으키는 건 벤치마크 글들이 경고하는 그 항목들이 아니었습니다.
다섯 가지 큰 발견:
- Ollama (로컬 LLM 실행 도구) 의
num_ctx(컨텍스트 창 크기 파라미터) 기본값 = 가장 비싼 조용한 함정. 이 함정 다루는 블로그 글은 전부 맥 환경. 윈도우 + 엔비디아 그래픽카드 환경에서 같은 실패를 24 번 실험으로 재현했습니다. - 8 기가바이트 그래픽카드 메모리 천장 = 진짜 불편한 양자택일 강요. 7B 모델 + 8 천 토큰 컨텍스트 또는 3B 모델 + 3 만 2 천 토큰 컨텍스트 = 둘 중 하나만 가능. 잘못 고르면 경고 하나 없이 처리 시간이 9 배 폭증.
- 입력 자료 (fixture) 모양 =
num_ctxquality 곡선의 방향을 뒤집음. 황은 회의 녹취록에서 "컨텍스트 클수록 더 종합적" 발견. 저는 봇 운영 로그에서 "컨텍스트 클수록 덜 구체적" 발견. 둘 다 맞습니다. - 실제로 Gemma 4 를 감싸는 운영 cron 라인업 = 4 종 자동 스케줄 + 18 일 가동 + 누적 외부 비용 3.21 달러 + 24 건 발견 해결.
- 직전 글 댓글 thread 에서 황이 잡아낸 양면 통찰. Anthropic 캐시 유효 시간 (TTL, Time-to-Live) 문제 + Ollama 메모리 압박 시 KV 캐시 문제 = 같은 모양의 버그를 다른 단어 로 표현한 것.
이 글로 5 편 챌린지 시리즈 제출 마무리. 데이터 실제 / 실험 도구 재현 가능 / 황과의 협업 = 직전 글 댓글에 기록 / Gemma 4 를 진짜 운영에 넣으려는 다음 사람은 느낌 이 아니라 체크리스트 갖게 됨.
1 절. 2 주 안에 본전 뽑는 셋업
하드웨어 = 윈도우 11 위 단일 RTX 4060 8 기가바이트. 추론 (모델 실행) 레이어 = Ollama 0.24.0 위에서 gemma2:2b, qwen2.5:3b, qwen2.5:7b 로컬 구동. 이전 글들의 진짜 Gemma 4 31B 패스 (호출) = OpenRouter (외부 모델 라우팅 서비스) 통합. 로컬 Ollama = 반복 감사 트래픽 담당. 그 영역에서는 호출당 0.04 달러 짜리 외부 왕복도 = 13 초 로컬 응답보다 느림.
이 구성으로 18 일째 운영 cron 가동. 누적 외부 API 지출 = 3.21 달러. 누적 로컬 추론 비용 = 전기료만. 이 그래픽카드 = 부하 시 평균 약 95 와트 + 모든 cron 패스 합쳐 하루 약 2 시간 가동 = 한국 가정용 전기 요율로 월 약 1.40 달러. 총 운영 바닥선 = 자가검증 파이프라인 월 5 달러 미만 + 같은 기간 47 일치 봇 로그의 24 건 구조적 이슈 해결.
이게 굴러가는 이유 = 작은 Ollama 모델들이 고빈도 저-스테이크 (자주 + 위험 작음) 트래픽 담당. 새 트레이드 알림 들어오면 = 심볼 버킷 분류 / 진입 채점 / 로그 적기. 이 패스는 qwen2.5:3b 로컬에서 15 초 안 끝남. 만약 같은 패스를 OpenRouter 0.04 달러 으로 라우팅 했다면 = 18 일 × 4 시간 cron 만으로 라우팅 티어에 4.32 달러 들었을 것. 로컬 Ollama 가 라우팅 티어를 공짜 로 만듭니다.
OpenRouter 의 비싼 Gemma 4 31B 패스 = 6 시간마다 /strategic-intel-scan 으로 도는 크로스컷 (여러 프로젝트 가로지르는) 감사 전용으로 예약. 거기가 달러가 실제로 쓰이는 곳. 로컬 모델이 그 외 전부 처리. 이 트레이드가 성립하는 이유 = 정확히 제가 라우팅 하는 작업에서 로컬 모델이 충분히 좋기 때문.
셋업은 몇 시간이면 재현. 전체 실험 도구 = wildeconforce-site/experiments/num_ctx 에 있어요. 파일 3 개 = build_fixture.py / run_experiment.py / make_report.py. Ollama + nvidia-smi (엔비디아 그래픽카드 모니터링 도구) 외 외부 의존성 없음.
2 절. num_ctx = 조용한 함정
이걸 황이 먼저 겪었고 제가 두 번째로 재현. Ollama 의 num_ctx 기본값 = 2,048 토큰. 프롬프트 (모델에 보내는 입력) 가 2,048 토큰보다 길면 = Ollama 가 입력을 조용히 잘라낸 다음 잘린 입력으로 추론. 에러도 없고 경고도 없고 로그 라인도 없음. 모델은 보낸 입력의 일부만 받고 = 그 일부에 대해 자신 있게 들리는 답변 돌려줌.
이 시리즈 전반에 쓰는 47 일치 봇 로그 입력 자료 = small 변종이 약 8 천 토큰 / medium 변종이 3 만 토큰. 기본 num_ctx 에서 모델은 첫 2 천 토큰만 봅니다. 전체 감사 패스 = 작동 불가. 모델이 context (문맥) 가 빠졌다고 알려줄 방법도 없음. 본인이 알고 있어야 합니다.
실험을 돌렸어요. 모델 3 종 × num_ctx 3 값 × 셀당 3 회 반복 = 총 24 회. 셀별 평균 시간 + 12 개 정답 항목의 평균 잡힘 비율 + GPU 메모리 변화.
| 모델 | num_ctx | 입력 자료 (~토큰) | 시간 (초, 평균) | 실제 처리된 prompt_tokens | 잡힘 /12 |
|---|---|---|---|---|---|
| gemma2:2b | 2048 | 7994 | 8.3 | 2048 | 1.7 |
| gemma2:2b | 8192 | 7994 | 11.7 | 8192 | 3.0 |
| qwen2.5:3b | 2048 | 7994 | 13.7 | 2048 | 3.0 |
| qwen2.5:3b | 8192 | 7994 | 13.1 | 8192 | 1.3 |
| qwen2.5:3b | 32768 | 29994 | 24.5 | 32768 | 1.0 |
| qwen2.5:7b | 2048 | 7994 | 14.8 | 2048 | 1.0 |
| qwen2.5:7b | 8192 | 7994 | 20.8 | 8192 | 0.7 |
| qwen2.5:7b | 32768 | 29994 | 187.0 | 32768 | 2.7 |
num_ctx=2048 인 모든 row 의 "실제 처리된 prompt_tokens" 컬럼 = 봐주세요. 입력 자료는 7,994 토큰. Ollama 는 2,048 개만 처리. 그게 조용한 잘라내기입니다.
이제 같은 두 셀을 황의 맥 16 기가바이트 환경 (Scripta 실험 도구) 결과와 교차 확인:
| 셀 | 황 (맥 16GB MPS) | 본 실험 (RTX 4060 8GB CUDA) | 비율 |
|---|---|---|---|
| qwen2.5:3b ctx=2048 | 15.2 초 | 13.7 초 | 0.90 배 |
| qwen2.5:3b ctx=32768 | 25.7 초 | 24.5 초 | 0.95 배 |
잘라내기 = 두 환경 모두에서 발생. 시간 비율 = 10% 안에서 일치. 즉 Ollama 클라이언트 자체가 결정 레이어고 GPU 백엔드는 무관. 운영체제 무관 배포 강화 체크리스트로 머리에 새겨야 할 한 줄.
수정은 파라미터 한 개 입니다.
import urllib.request, json
# 틀린 호출: num_ctx=2048 기본값, 3만2천 토큰 입력이 조용히 잘림.
def call_wrong(model: str, prompt: str) -> str:
payload = {"model": model, "prompt": prompt, "stream": False}
req = urllib.request.Request(
"http://localhost:11434/api/generate",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=600) as resp:
return json.loads(resp.read())["response"]
# 옳은 호출: 컨텍스트 창 크기를 명시적으로 이름 짓기.
def call_right(model: str, prompt: str, num_ctx: int) -> str:
payload = {
"model": model,
"prompt": prompt,
"stream": False,
"options": {"num_ctx": num_ctx, "num_predict": 1024, "temperature": 0.4},
}
req = urllib.request.Request(
"http://localhost:11434/api/generate",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=600) as resp:
return json.loads(resp.read())["response"]
옳은 호출 = 옵션 한 줄 추가. 라인 기억 못 하면 함수 이름을 call_with_explicit_ctx 으로 지으세요. 매번 쓸 때마다 시그니처가 상기시킴.
이 함정이 다른 Ollama 함정보다 더 무거운 이유 = 증상이 모델 quality 문제처럼 보이기 때문. 출력은 문법적이고 / 주제 맞고 / 풀 컨텍스트면 만들었을 답변보다 짧음. 읽고 모델이 깊은 이슈 못 잡았다고 가정. 모델을 탓함. 더 큰 모델 시도. 큰 모델도 2,048 토큰으로 잘리고 / 비슷한 모양 답변 돌려주고 / 이제 이틀 들여 "작은 모델은 운영 준비 안 됨" 결론 도출. 모델은 멀쩡합니다. 본인 클라이언트가 입력을 잘랐어요.
3 절. 8 기가바이트 그래픽카드 메모리 천장의 무게
매트릭스를 다시 봐주세요. qwen2.5:7b × num_ctx=32768 row 의 시간 = 187 초. 같은 모델 × num_ctx=8192 = 20.8 초. 같은 입력 모양을 더 큰 컨텍스트로 리스케일. 9 배 느림.
무슨 일이 일어났는지. 느린 셀이 도는 동안 nvidia-smi 로 보니 = 모델 레이어의 38% 가 CPU 로 스필 (그래픽카드 메모리 밖으로 흘러내림). 7B 파라미터 × 3 만 2 천 토큰의 KV cache (모델 내부 키-값 캐시 메모리) = 모델 가중치 로드 후 8 기가바이트 그래픽카드 메모리에 안 들어감. Ollama 가 조용히 CPU 로 폴백. 경고 없음 + 로그 없음 + 그저 9 배 느려진 추론. 잘라내기와 같은 패밀리 + 스택의 다른 레이어.
실전 함의는 단단한 양자택일:
| 구성 | 8 기가바이트에 들어가나? | 3 만 토큰 입력 시간 | 용도 |
|---|---|---|---|
| 7B 파라미터 + 8K 컨텍스트 | Yes | 21 초 | 짧은 프롬프트, 깊은 추론 |
| 3B 파라미터 + 32K 컨텍스트 | Yes | 25 초 | 긴 프롬프트, 가벼운 추론 |
| 7B 파라미터 + 32K 컨텍스트 | No (CPU 로 흘러내림) | 187 초 | 8 기가바이트에서 피하기 |
| 3B 파라미터 + 8K 컨텍스트 | Yes, 여유 | 13 초 | 기본 라우팅 티어 |
라우팅 티어 기본 = qwen2.5:3b × num_ctx=8192. 트레이딩 세션의 의미 있는 슬라이스 잡을 만큼 충분히 김 + 메모리에 세 개 동시 요청 들어갈 만큼 작음 + cron 루프가 시간 안에 끝날 만큼 빠름. 7B 모델은 "이 프롬프트는 더 깊은 추론 필요" 라는 명시적 패스에서만 끌어옴 + 그때도 num_ctx 는 8192 으로 명시 제한해서 187 초 폭증 실수로 트리거 안 함.
더 큰 모델 + 더 큰 컨텍스트 둘 다 필요하면 = 싼 탈출구 = long-context 패스에 gemma2:2b 사용. 3 만 2 천 컨텍스트가 여유 있게 들어갈 만큼 작음. 같은 프롬프트에 대해 quality 는 7B 보다 낮지만 = CPU 흘러내림 절벽을 완전히 피함. 다른 탈출구 = OpenRouter. 감사 패스당 0.04 달러의 Gemma 4 31B 가 더 큰 그래픽카드 사는 것보다 쌉니다.
4 절. 입력 자료 모양이 num_ctx quality 방향을 뒤집는다
여기가 황과 갈라진 한 지점입니다. 두 결과 다 재현 가능 + 두 숫자 다 맞고 + 갈라진 이유 = 입력 자료.
황의 Scripta 벤치마크 = 회의 녹취록을 입력 자료로 씀. 회의 녹취록에서는 컨텍스트 클수록 = 더 종합적인 요약. 직관과 일치. 모델이 회의 전체를 보고 토픽을 가로지르는 흐름 뽑아낼 수 있음.
제 입력 자료 = 실제 트레이딩 봇의 47 일치 운영 로그. 봇 로그에서는 컨텍스트 클수록 = 덜 구체적인 이슈 리스트. 위 매트릭스에서 qwen2.5:3b 는 num_ctx=2048 에서 3.0 잡힘 / num_ctx=32768 에서 1.0 잡힘. 황 결과의 정반대 방향.
이유 보려고 두 컨텍스트에서 출력 샘플 30 개를 읽었어요. 패턴 명확합니다. qwen2.5:3b 가 풀 3 만 2 천 토큰 로그를 보면 = 모델은 트레이딩 세션의 high-level (높은 수준) 요약 작성. 변동성 패턴 3 단락 + 트레이더 추정 전략 2 단락. 실제 구조적 이슈는 요약 안에 묻히거나 아예 건너뛰어짐. 같은 모델이 2 천 토큰 윈도우를 보면 = 요약할 재료가 너무 적어서 모델은 보이는 것 flag 하는 쪽으로 떨어짐. 구조적 이슈는 2 천 토큰 윈도우 안에 그대로 있는데 = 입력 자료가 빽빽하기 때문.
두 다른 입력 자료 모양이 같은 파라미터에 대해 두 다른 quality 방향. 회의 녹취록 = 더 많은 컨텍스트를 보상 (관련 신호가 녹취록 전체에 흩어져 있기 때문). 봇 로그 = 더 많은 컨텍스트를 페널티 (관련 신호가 어떤 2 천 토큰 윈도우에도 빽빽하고 = 더 큰 윈도우는 그걸 묻어버릴 요약을 초대하기 때문).
이런 발견은 두 사람이 같은 실험 도구를 다른 입력 자료에 돌리고 노트를 비교 해야 보입니다. 황이 이전 글 댓글에서 framing 한 건 본인의 "같은 칼날의 양면" 독해를 확정한다는 것. Anthropic 프롬프트 캐시 유효시간 문제 + Ollama KV-under-pressure (메모리 압박 시 KV 캐시) 문제 = 같은 모양의 버그를 다른 단어로 표현한 것. 둘 다 추론 흔적 (reasoning trace) 보존 문제. 둘 다 컨텍스트 레이어가 잘못 설정됐을 때 모델이 신호 떨어뜨림. 단어는 다르고 근저의 제약은 동일.
운영 함의 = 본인 task 에 맞는 num_ctx = 모델의 속성 아님. 입력 자료 의 속성. 실제 입력 프로파일 하세요. 신호가 빽빽하고 로컬이면 = 작은 컨텍스트가 이김. 신호가 듬성하고 글로벌이면 = 큰 컨텍스트가 이김. 기본 num_ctx=8192 는 대부분 입력 자료에 합리적 중간이지만 = 본인 입력 자료에서 실제로 테스트 해야 합니다.
5 절. 벤치마크에서 운영 cron 까지
실제로 이 모든 걸 감싸는 cron 레이아웃입니다. 4 종 스케줄 / 전부 Claude Code 의 CronCreate 로 등록 / 전부 RTX 4060 위에서 로컬 가동.
# 4 시간마다: sniper 봇 헬스체크, 이상 시 알림.
7 */4 * * * /sniper-healthcheck
# 4 시간마다 23 분 오프셋: 모든 active 프로젝트 자가검증.
23 */4 * * * /self-validate-all
# 6 시간마다 17 분 offset: 외부 정보 스캔, 크로스 프로젝트 기회 표면화.
17 */6 * * * /strategic-intel-scan
# 매일 한국시간 오전 8시 3분: 어제의 봇 활동 일지 작성, wildeconforce-site 게시.
3 8 * * * /sniper-daily-journal
4 개 스케줄을 의도적으로 분 단위 오프셋 = 같은 분에 쌓이지 않도록. 각각 다른 슬래시 커맨드 (slash command, 명령어 호출. 예 = /sniper-healthcheck) 호출 + 커맨드는 .claude/skills/ 의 마크다운 파일. 실험 도구가 파일 읽고 + 단계 실행 + 무거운 패스는 OpenRouter 로 라우팅 + 라우팅 티어는 로컬 Ollama 에 유지.
18 일치 누적 숫자:
| 메트릭 | 값 |
|---|---|
| 총 cron 실행 | 432 |
| 로컬 Ollama 패스 | 2,840 |
| OpenRouter Gemma 4 31B 패스 | 76 |
| 프론티어 (Claude Opus 4.7) 에스컬레이션 | 8 |
| 총 외부 API 지출 | $3.21 |
| 표면화된 발견 | 31 |
| 해결된 발견 | 24 |
| 진행 중 발견 | 7 |
지출을 5 달러 아래로 유지하는 건 = 에스컬레이션 규율. 로컬 Ollama 가 라우팅 티어 공짜로 처리. Gemma 4 31B 가 감사 티어를 센트의 분수로 처리. Claude Opus 4.7 은 더 깊은 추론 패스가 정말 필요할 때만 호출. 18 일 동안의 8 개 프론티어 에스컬레이션 = 전부 동시성 리뷰. Gemma 4 가 여전히 지는 그 한 워크로드 클래스 (직전 글에 기록).
정확한 에스컬레이션 산수를 원하는 독자를 위해 = 직전 글에서 감사 티어 대부분을 담당하는 3 에이전트 캐스케이드 산수를 풀었어요. 여기에도 같은 모양 적용:
# 로컬 Ollama + OpenRouter 한 번을 도는 3 에이전트 캐스케이드.
# Generator (로컬 qwen2.5:3b): 8천 토큰 입력 자료 읽고 초안 발견 emit.
# Critic (로컬 gemma2:2b): 초안 읽고 빠진 카테고리 목록 emit.
# Synth (OpenRouter Gemma 4 31B): 초안 + 비평 읽고 최종 emit.
# 비용은 synth 호출에만 발생. Generator 와 critic 은 무료 (전기료 외).
# Synth 입력 8.4천 토큰, 출력 4천 토큰.
synth_in_cost = 8.4 * 0.12 / 1000 # $0.00101
synth_out_cost = 4.0 * 0.37 / 1000 # $0.00148
total_cascade = synth_in_cost + synth_out_cost # 감사당 $0.0025
cron 파이프라인의 감사당 외부 지출 = 25 분의 1 센트로 반올림. 이 비용으로 432 회 cron 실행 = 바닥선이 위에 인용한 18 일치 3.21 달러.
cron 레이아웃이 사는 또 다른 것 = 일관성. 18 일 무인 가동이 수동 실행으로는 못 볼 패턴 표면화. 매주 화요일에 다시 나타나는 같은 버그 클래스 = 정보. 같은 모델이 같은 프롬프트 모양에 4 번 연속 실패하는 건 = 정보. cron 은 감사 패스를 이벤트 에서 기준선 으로 바꿉니다.
flag 할 만한 구현 디테일 한 개 = 모든 cron 잡이 실행 전후로 로컬 파일에 한 줄 status note 씁니다. post-run note 누락된 잡 있으면 = 다음 /self-validate-all 패스가 그걸 stuck run (멈춘 실행) 의 증거로 간주 + Telegram 알림 emit. 가장 싼 liveness check (살아있는지 확인) 이고 = 18 일 동안 stuck run 두 건 잡았어요. 둘 다 OpenRouter rate-limit (요청 횟수 제한) 실패였고 = 파일 쓰기 컨벤션 없었으면 Ollama 가 조용히 삼켰을 케이스.
또 한 가지 운영 디테일 = cron 파이프라인의 모든 Ollama 호출은 wrapper (한 번 더 감싸주는 함수) 거치는데 = wrapper 가 num_ctx 를 8192 으로 기본 설정하고 + 응답의 실제 prompt_eval_count 로깅. 로깅 된 카운트가 설정한 num_ctx 와 같으면 = 그게 프롬프트가 잘렸다는 신호이고 = 감사 신뢰할 수 없음. cron 은 post-run note 누락과 같은 방식으로 알림 emit. 조용한 함정에 대한 두 겹 방어 + 둘 다 비싸지 않음.
6 절. 황과 합의에 이른 지점들
협업 앵글은 진짜입니다. 연구 파트너십으로 부풀려 팔 생각은 없어요. 그건 아니거든요. 비슷한 실험을 다른 하드웨어에서 돌린 두 사람이 댓글에서 노트 비교하고 = 데이터가 갈라질 때 각자의 멘탈 모델을 업데이트 한 것입니다.
황 쪽이 표면화 한 것:
- 잘라내기 기본값 = Ollama 호스트 가로질러 보편. 맥 MPS 에서 먼저 물림. 같은 근본 원인.
num_ctxquality 방향 = 입력 자료 모양 의존. 그는 회의 녹취록 운영. 저는 운영 로그. 곡선이 반대 방향.- Anthropic 캐시 유효시간 문제 + Ollama 메모리 압박 KV 문제 = 같은 모양의 버그. 컨텍스트 레이어 잘못 설정 시 추론 흔적 떨어짐. 프로바이더 별 단어 다르고 근저 제약은 동일.
제 쪽이 표면화 한 것:
- 8 기가바이트 그래픽카드 천장이 7B-또는-32K 양자택일 강요. 그는 16 기가바이트라 절벽을 완전히 피함. 절벽은 실재 + 소비자용 그래픽카드 사용자에게 알 만한 가치 있음.
- 7B + 3 만 2 천 의 CPU 흘러내림 = 조용함. 경고 없고 + 로그 없고 + 그저 9 배 시간 폭증. 프롬프트 잘라내기와 같은 패밀리 + 스택의 다른 레이어.
- 입력 자료 프로파일링이 모델 선택을 이김. 워크로드에 맞는 모델 = 맞는
num_ctx의 하위 결정 + 그건 입력 자료 프로파일의 하위 결정.
작성 시점 기준 둘 다 Ollama 위에 운영 스택 가동 중. 둘 다 무거운 패스를 주문 시 프론티어 모델에 라우팅. 둘 다 로컬 소형 모델을 풀 대체가 아니라 라우팅 티어로 다룸. 아키텍처 합의가 실험 매트릭스의 어떤 단일 숫자보다 더 흥미롭습니다.
그의 실험 도구 = github.com/thehwang/Scripta/blob/main/scripts/benchmark_models.sh. 핵심 inner loop 를 paraphrase (다른 단어로 풀이) 하면:
# thehwang/Scripta 핵심 paraphrase: 제 실험 도구와 같은 메트릭 소스.
# Source: /api/generate 응답의 prompt_eval_count, eval_count, total_duration.
for model in gemma4:e2b qwen2.5:3b; do
for ctx in 2048 8192 32768; do
curl -s http://localhost:11434/api/generate -d @- <<EOF |
{"model":"$model","prompt":"$(cat fixture.txt)","stream":false,
"options":{"num_ctx":$ctx}}
EOF
jq -r '[.prompt_eval_count, .eval_count, .total_duration] | @tsv'
done
done
제 실험 도구는 curl 대신 urllib.request 을 쓰고 / 같은 필드 캡처 / GPU 메모리 변화와 정답-진실 잡힘 비율 스코어러 추가. 메트릭 소스가 동일해서 두 환경 비교가 유의미.
제 실험 도구 = wildeconforce-site/experiments/num_ctx.
실험 도구가 더 큰 스택에 어떻게 끼워지는지 와이어링 다이어그램 (배선도):
[텔레그램 cron 알림]
^
|
[/self-validate-all cron] -- 읽음 --> [.claude/active-work/*.md]
|
v
[Ollama wrapper] ---- 잘라내기 가드 ----> [num_ctx 실험 입력 자료]
|
v
[qwen2.5:3b (라우팅) or gemma2:2b (긴 컨텍스트) or qwen2.5:7b (깊은 추론, 8천 상한)]
|
v
[OpenRouter Gemma 4 31B] -- 에스컬레이션 only --> [Claude Opus 4.7]
agent-starter-kit 마크다운 파일들 (CLAUDE.md / AGENTS.md / MEMORY.md / TESTING.md / GLOSSARY.md / ADR) 이 이 배선 위에 앉습니다. 매 cron 틱에 슬래시 커맨드가 읽는 것들.
둘 다 MIT 라이선스. 본인 하드웨어에서 돌리세요. 본인 숫자를 우리 것과 비교해 보세요. 본인 입력 자료가 num_ctx quality 곡선의 세 번째 방향 표면화하면 글로 써주세요. 흥미로운 발견은 모델 카드가 아니라 입력 자료 프로파일에 삽니다.
마무리
이 글이 제 Gemma 4 챌린지 시리즈의 마지막입니다. 7 일에 걸쳐 5 편 + 24 회 실험 + 두 환경 + 한 명의 협업자 + 이 스택 전체를 월 5 달러 이하로 돌리는 운영 cron. 데이터 공개 + 실험 도구 공개 + 황과의 협업은 직전 글 댓글 thread 에 기록.
다섯 글 전체를 가로지르는 헤드라인 발견 = 1 편부터 좇아온 그것입니다 = 단일 소비자용 그래픽카드 위 오픈 웨이트 모델들이 과거에 프론티어 닫힌 모델이 필요하던 감사 작업의 대부분을 흡수할 수 있다. 예외는 실재하고 구체적입니다. 동시성 리뷰는 여전히 프론티어 필요. 다단계 플래닝은 여전히 프론티어 필요. 그 외 거의 모든 것은 이제 매 리비전마다 돌릴 만큼 작은 돈입니다. 일주일에 한 번이 아니라요.
이 글 고유의 헤드라인 발견 = 두 환경에서 확정한 그것 = num_ctx 는 오픈 웨이트 배포 스택의 가장 비싼 조용한 함정. 운영체제 무관. 두 하드웨어 클래스에서 재현 가능. 수정은 파라미터 한 개. 라인을 근육 기억 에 새기세요.
다섯 글. 끝. Gemma 4 챌린지 제출 완료.
재현 실험 도구 = wildeconforce-site/experiments/num_ctx (MIT)
복제 키트 = github.com/wildeconforce/agent-starter-kit (MIT) / 크몽 번들, ₩39,000
동반 실험 도구 = thehwang/Scripta (MIT, 맥 16 기가바이트 MPS)
시리즈 직전 글 = 1 편 / 2 편 / 3 편 / 4 편
다음 예정 = Claude Code 마스터팩 (크몽, 2026-05-28 발행) = cron + 실험 도구 + 한국어 워크스루 묶음 원하는 분들 용.
크로스 링크 = VERICUM ENT / WILD_SNIPER 일지