2026-08-21 (금) 개발일지
오늘은 여러 프로젝트를 동시에 진행하면서 각각 다른 성질의 문제들을 마주쳤다. 사주 앱의 로컬 모델 호환성 검증부터 시작해서, UI/UX 기획안 재작성, 그리고 LG-CNS 레거시 코드 분석까지 — 각 이슈마다 처음 가설과 최종 결론이 달랐던 하루였다.
사주 앱 로컬 모델 실행 가능성 — M1 Pro 32GB는 “VRAM 없음”이 아니라 “통합 메모리”였다
M1 Pro 맥북에서 사주 앱 백엔드를 로컬 모델로 돌릴 수 있을지 검토해야 했다. 처음 질문은 단순했다: “램이 32GB인데 GPU VRAM은 없는 거 아닌가? 로컬 모델 돌릴 수 있나?” 직관적으로는 VRAM이 없으면 GPU 추론이 불가능할 거라고 생각했다.
하지만 실제로 확인해보니 Apple Silicon은 CPU와 GPU가 같은 메모리 공간을 공유하는 통합 메모리(UMA) 아키텍처였다. 별도 VRAM 칩이 없는 대신, 32GB 중 대략 24GB를 GPU가 자유롭게 쓸 수 있다는 뜻이었다. 오히려 일반 PC(VRAM 8GB + RAM 16GB)보다 유리한 상황이었다.
| 구성 | GPU 가용 메모리 |
|---|---|
| M1 Pro (32GB 통합) | ~24GB (CPU와 공유) |
| 일반 PC (RTX 4060) | 8GB (VRAM만) |
| 일반 PC (RTX 4090) | 24GB (VRAM만) |
그제서야 모델 선택이 명확해졌다. 8B급 모델(약 5GB 메모리 필요)이면 충분했고, 실제로 시스템에 0.5GB 정도 여유가 있었으니 EXAONE 4.0 32B(한국어 벤치마크 KMMLU-Pro 67.7점)나 Qwen3-Coder-30B(추론 속도 42.8 tok/s)를 후보로 삼을 수 있었다.
검증: 한국 LLM 벤치마크 데이터를 56개 소스에서 수집해 비교표를 만들었고, 최종 권장은 EXAONE 4.0 32B(한국어 성능 + 추론 능력) 또는 Qwen3-Coder-30B(속도 중심)로 정리됐다. 맥북 스펙이 충분하다는 확인이 나왔으니 이제 실제 모델 통합은 local_model_compat.py에서 진행하면 된다.
남은 과제: 모델 다운로드 후 백엔드 API(/health 엔드포인트는 이미 127.0.0.1:8010에서 정상 응답 중)와 통합하는 단계.
사주 UI/UX 기획안 재작성 — 텍스트만 있는 문서에서 실제 스크린샷 2단 레이아웃으로
기존 uiux_overview.html 기획안이 있었는데, 검토 결과 스펙 텍스트만 있고 실제 앱 화면 스크린샷이 없었다. 원본 기획안을 보니 좌측에 폰 목업 이미지, 우측에 스펙 텍스트(초록 번호 배지 + 한글명 + 영문명 + GOAL/COMPONENTS/INTERACTION/STATE 정보)가 2단으로 정렬돼 있었다.
처음에는 “텍스트 박스로 충분하겠지” 라고 생각했다가, 원본과 비교하면서 시각적 품질 격차가 명확했다. 단순 텍스트는 문서처럼 보이지만, 실제 앱 화면과 함께 있어야 “이게 진짜 앱 기획서다” 라는 신뢰가 생긴다는 걸 깨달았다.
시도 과정:
- 첫 번째: 텍스트 박스만 배치 → 원본과 비교해 부족함 인식
- 두 번째: 스크린샷 경로 매핑 시도 → 업로드 한도 초과로 실패 (9,681px 세로 이미지)
- 세 번째: 1600px 고정 폭 + 2단 레이아웃으로 재설계 → HTML/CSS 단일 파일로 완성
최종 해법: uiux_overview.html을 6개 섹션(표지 / 유저 플로우 / 화면 스펙 / 결제 모델 / 신뢰·안전 / 디자인 시스템)으로 재구성했다. 화면 스펙 섹션에는 31개 스크린샷을 모두 통합했고, 결제 지점(₩1,900)만 주홍색으로 강조해 “이번 업데이트의 핵심”을 시각적으로 드러냈다.
디자인 방향: 고급 한지·편집 디자인 톤. 표지는 먹빛 풀블리드에 주홍 緣 인장, 본문은 한지 크림 배경 + 명조 제목/Pretendard 본문의 절제된 2단 위계. 외부 리소스 없이 순수 HTML/CSS만 써서 어디서나 한 번에 열린다.
검증: 1600px 고정 폭에서 모든 텍스트가 overflow 없이 정렬되고, 결제 강조 노드(09)가 명확히 읽히는 걸 확인했다. Chrome headless로 세로 긴 PNG 렌더링도 준비 중.
LG-CNS 레거시 코드 분석 — GitLab 익명 접근 불가에서 로컬 AST 추출로 전환
terasys-rd/lgchem-app 저장소를 분석해야 했는데, 내부 GitLab 서버(http://<INTERNAL_IP>)에 익명 접근이 전부 막혀 있었다. /api/v4/version을 쳤더니 401 Unauthorized, 프로젝트 목록 API도 []만 반환했다. 로컬 자격증명(~/.config/glab-cli)도 없었다.
처음엔 “GitLab 접근이 막혀 있으면 분석 불가” 라고 생각했다. 하지만 저장소가 이미 로컬에 클론돼 있다는 걸 깨달았고, 읽기 전용으로 파일 시스템만 탐색해도 충분하다는 결론에 도달했다.
실행한 작업:
- AST 추출: 8개 문서 파일(TypeScript, JSON, Markdown)을 파싱해 256개 노드 / 526개 엣지 그래프 생성
- 의미 추출: 서브에이전트 2개를 병렬로 투입해 각 파일의 개념 계층 추출
- 학습 가이드 생성:
LEARNING_GUIDE.md(23KB, Mermaid 다이어그램 6개 포함) — 이 프로젝트를 처음 보는 사람도 A부터 Z까지 따라갈 수 있도록 작성
발견한 버그 3건:
- 🔴
usePagingQuery.ts:84— 서브쿼리 폴링setIntervalID를 지역변수에 담아서, 언마운트 정리(resetInterval)가 못 잡음. 필터를 쓰다가 메뉴를 옮기면 폴링이 계속 돌면서 메모리 누수 발생 - 🟡 라우팅 이중 관리 — react-router를 안 쓰고 수동 상태 관리로 20개 화면을 조작 (의존성 최소화는 좋지만 유지보수 리스크)
- 🟡 Logpresso 디자인 시스템 규약 이중화 — 구 규약(
DESIGN.md765줄) vs 신 규약(design.logpresso.com) 혼재
검증: git status가 빈 줄 — 저장소는 클론 직후 그대로 유지됐다. 읽기 전용으로만 작업했으니 커밋·푸시 없이 분석 산출물만 graphify-out/ 디렉토리에 남겼다.
산출물:
LEARNING_GUIDE.md— 23KB, 완전 학습 문서MEMORY.md— 핵심 개념 메모.graphify_chunk_01.json— 133개 노드, 183개 엣지, 3개 하이퍼엣지 그래프GRAPH_REPORT.md— 감사 리포트
남은 과제: 버그 3건의 우선순위 정리 및 수정 계획 수립. 특히 폴링 누수는 성능 영향이 직접적이라 우선 처리 권장.
오늘의 한줄
가설이 틀렸을 때 재빠르게 방향을 바꾸는 게 중요했다 — M1의 “VRAM 없음”은 “통합 메모리”였고, GitLab 접근 불가는 로컬 파일 시스템 분석으로 우회했고, 기획안 텍스트만으로는 부족했을 때 스크린샷 2단 레이아웃으로 전환했다. 각 이슈마다 처음 직관과 최종 해법이 달랐다는 게 오늘의 패턴이었다.