AI 용어 사전 — 토큰, 컨텍스트, 환각... 뜻만 알면 절반은 끝난다

이미지
이 글은 새로 시작하는 AI 입문 연재의 첫 번째 글이다. 이 연재는 AI를 한 번도 써 본 적 없는 사람을 위해 쓴다. 그런데 첫 관문은 기술이 아니라 말이다. 토큰, 컨텍스트, 환각 같은 단어가 설명 없이 튀어나오는 순간부터 글이 읽히지 않는다. 그래서 첫 글에서는 앞으로 계속 나올 용어를 하나씩 짚는다. 용어마다 일상 비유 하나와, 그 말을 알면 무엇이 달라지는지를 붙였다. 외울 필요는 없다. 읽고 나서 "아, 그게 그 말이었구나" 정도만 남아도 충분하다. 대화를 이루는 기본 용어 LLM과 생성형 AI LLM 은 '거대 언어 모델'의 줄임말이다. 어마어마한 양의 글을 읽고 말의 패턴을 익힌 프로그램이라고 보면 된다. 생성형 AI 는 그보다 넓은 말로, 없던 결과물을 새로 만들어 내는 AI 전체를 가리킨다. 글을 만들면 언어 모델, 그림을 만들면 이미지 생성 AI다. 왜 중요한가. 흔히 말하는 'AI 챗봇'은 대부분 LLM, 즉 글을 다루는 데 특화된 도구다. 계산기나 검색 엔진과는 잘하는 일이 애초에 다르다는 뜻이다. 토큰 AI는 글을 글자 단위로 세지 않는다. 토큰 이라는 조각 단위로 센다. 한글은 한 글자가 대략 한 토큰 정도라고 생각하면 크게 어긋나지 않는다. 택배 요금을 무게로 매기듯, AI는 처리량을 토큰으로 잰다. 왜 중요한가. 무료 사용 한도, 유료 요금, 한 번에 넣을 수 있는 문서 분량이 모두 토큰으로 계산된다. "길게 쓰면 비싸진다"는 말의 근거가 여기에 있다. 컨텍스트 윈도우 AI가 한 번에 펼쳐 놓고 볼 수 있는 분량이다. 책상 넓이에 비유할 수 있다. 책상이 넓으면 자료를 여러 개 올려놓고 볼 수 있지만, 좁으면 새 자료를 놓을 때 먼저 있던 것을 치워야 한다. 대화가 길어지면 앞부분이 이 책상에서 밀려난다. 왜 중요한가. 오래 이어 간 대화에서 AI가 갑자기 앞 내용을 잊는 것은 고장이 아니다. 구조상 당연한 일이다. 주제가 바뀌면 새 대화를 여...

GraphRAG 파이프라인 구축 - 문서 뭉치에서 지식그래프까지

이미지
지난 글에서 온톨로지와 지식그래프의 개념을 정리하면서, 벡터 RAG가 관계 질문에 약하다는 이야기로 마무리했다. 이번에는 그 대안인 GraphRAG를 실제로 만들어 본다. 문서 뭉치를 넣으면 LLM이 엔티티와 관계를 뽑아내고, 그것으로 그래프를 만들고, 질문이 들어오면 벡터로 진입점을 찾은 뒤 그래프를 따라 답에 필요한 조각을 모아 오는 파이프라인이다. 미리 밝혀 두면, 이 글의 코드는 두 종류다. LLM 호출이 필요한 추출 단계는 문법과 스키마만 정확히 적고 출력은 예시로 표기했다. 반면 정규화·그래프 구축·하이브리드 검색은 실제로 돌려서 나온 출력을 그대로 붙였다. 어느 쪽인지는 매번 표시하겠다. 1. 전체 그림부터 - 두 개의 파이프라인 GraphRAG는 사실 별개의 파이프라인 두 개다. 하나는 문서가 바뀔 때만 도는 인덱싱 , 다른 하나는 질문마다 도는 질의 다. 이 둘을 분리해서 생각하지 않으면 설계가 금세 엉킨다. 인덱싱은 비싸고 느려도 되지만 질의는 싸고 빨라야 하기 때문이다. GraphRAG의 두 파이프라인. 강조된 두 단계가 비용과 품질을 결정한다. 벡터 RAG와 비교하면 추가된 것은 ②관계 추출 과 ③그래프 확장 두 단계뿐이다. 나머지는 이미 익숙한 청킹과 임베딩이다. 그래서 기존 RAG 파이프라인이 있다면 통째로 갈아엎을 필요 없이 이 두 단계를 얹는 식으로 접근하는 편이 낫다. 2. 청킹 - 벡터 RAG와 기준이 다르다 벡터 RAG의 청킹 기준은 "이 조각만 읽고 답할 수 있는가"다. 그래서 400~500자 정도로 잘게 자른다. 그런데 GraphRAG의 청킹 기준은 다르다. "이 조각 안에 주어와 목적어가 함께 들어 있는가" 다. 문장이 잘려서 "이 서비스는 그것에 의존한다"만 남으면 LLM이 뽑을 수 있는 관계가 없다. 그래서 GraphRAG용 청크는 벡터 RAG보다 크게 잡는다. 800~1200자 정도, 문단 경계를 지키면서 자르는 것이 무난했다. 겹침도 조금 ...

파워쉘 keytool 한글 깨짐(물음표 ???) 해결 - 안드로이드 키스토어 생성 시 인코딩 문제

이미지
안드로이드 앱을 출시하려면 keytool로 업로드 키스토어(.jks)를 만들어야 한다. 그런데 윈도우 11 파워쉘에서 keytool을 실행하면 안내 문구가 ? ??? ???? ??: 처럼 전부 물음표로 깨져 나와서, 지금 무엇을 입력하라는 것인지 알 수 없는 상황이 생긴다. 이 글은 이 한글 깨짐의 원인과 두 가지 해결 방법, 그리고 함께 마주치게 되는 JKS 포맷 경고까지 정리한 것이다. 왜 물음표로 깨지는가 이것은 글꼴 문제가 아니라 인코딩 불일치 문제다. keytool은 자바(JVM) 프로그램이라 윈도우의 한국어 로케일을 따라 안내문을 한글로 출력하는데, JVM이 내보내는 출력 인코딩과 콘솔이 기대하는 인코딩이 서로 맞지 않으면 한글이 전부 ? 로 바뀐다. 깨진 문구의 정체는 "키 저장소 비밀번호 입력:" 같은 평범한 한글 안내문이다. 해결 방향은 두 가지다. 한글 출력 자체를 없애거나(영어로 강제), 인코딩을 UTF-8로 통일하거나. 키스토어 생성처럼 한 번 실행하고 마는 작업이라면 영어 강제 쪽이 훨씬 간단하다. 방법 1 (추천): 안내문을 영어로 강제 출력 keytool에 -J 옵션으로 JVM 언어를 영어로 지정하면 된다. 한글 자체가 나오지 않으니 깨질 일도 없다. & "C:\Program Files\Android\Android Studio\jbr\bin\keytool.exe" -J-Duser.language=en -J-Duser.country=US -genkey -v -keystore $env:USERPROFILE\my-upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload 이렇게 실행하면 "Enter keystore password:", "What is your first and last name?"처럼 영어로 또박또박 물어봐서 헷갈릴 일이...

온톨로지와 지식그래프 기초 - DB 스키마와 무엇이 다른가

이미지
"온톨로지"라는 단어를 AI 문서에서 처음 보면 대개 두 번 놀란다. 한 번은 철학 용어가 왜 여기 나오나 싶어서, 또 한 번은 설명을 읽어도 "그래서 데이터베이스랑 뭐가 다른데?"가 해결되지 않아서다. 이 글은 그 두 번째 질문에 답하는 것을 목표로 한다. 개념을 그림으로 정리하고, 마지막엔 파이썬 20여 줄로 온톨로지의 핵심 기능을 직접 돌려본다. 결론부터 말하면 온톨로지는 "이 도메인에 어떤 종류의 것들이 존재하고, 그것들이 서로 어떻게 연결되는지"를 기계가 읽을 수 있게 못 박아 둔 규칙 이다. DB 스키마와 결정적으로 다른 점은 하나다. DB 스키마는 저장 구조 를 정의하고, 온톨로지는 추론 규칙 을 정의한다. 그래서 온톨로지는 저장하지 않은 사실을 만들어낼 수 있다. 온톨로지는 무엇으로 이루어져 있나 온톨로지를 구성하는 요소는 사실 네 개뿐이다. 이름은 낯설지만 개념은 객체지향 프로그래밍을 해본 사람이면 이미 아는 것들이다. 클래스(Class) — 개념의 범주. Service , Person . 자바의 클래스와 같은 자리다. 인스턴스(Individual) — 실제 개체. OrderApi , alice . 속성(Property) — 개체를 잇는 관계. owns , dependsOn . 여기서 관계는 필드가 아니라 일급 시민 이다. 이것이 첫 번째 차이점이다. 공리(Axiom) — 그 관계가 지켜야 할 규칙. " owns 의 주체는 반드시 Person 이다", " dependsOn 은 이행적이다". 여기가 온톨로지의 심장이다. 온톨로지의 네 요소. 위 두 층은 흔한 타입 시스템이지만, 맨 아래 '공리'가 나머지를 다르게 만든다. 주목할 점은 다이어그램 맨 아래다. 우리는 alice 가 Person 이라고 말한 적이 없다 . 단지 alice owns OrderApi 라는 사실 하나와, " owns 의 주체는 Per...

Flutter에서 로컬 LLM 연동하기 — 서버 없이 온디바이스로 AI 돌리기

이미지
앱에 AI 기능을 넣을 때 보통은 Claude 같은 서버 API를 부른다. 그런데 호출량이 늘수록 비용이 따라 늘고, 오프라인에서는 아예 동작하지 않는다는 한계가 있다. 그래서 이번에는 반대 방향을 실험해 봤다. 서버 없이, 스마트폰 안에서 직접 도는 소형 LLM을 Flutter 앱에 붙이는 것 이다. 결론부터 말하면 "생각보다 잘 되지만, 쓸 곳을 잘 골라야 한다"였다. 실제로 해본 순서대로 정리한다. 1. 온디바이스 추론이 되는 조건 모든 기기에서 모든 모델이 도는 것은 아니다. 관건은 모델 파일 크기와 기기 RAM 이다. 대략의 감각은 이렇다. 모델은 4bit 양자화 기준으로 파라미터 수의 절반 남짓한 용량이 된다. 1B 모델이면 수백 MB, 4B급이면 2~4GB 수준의 파일을 앱이 내려받아 들고 있어야 한다. 추론 중에는 모델 크기 이상의 메모리가 필요하다. RAM 8GB 이상의 비교적 최신 기기라면 2~4B급, 보급형 기기라면 1B 이하가 현실적인 선이다. 모델 파일을 APK에 넣으면 스토어 용량 제한에 걸리므로, 첫 실행 시 다운로드하는 구조가 일반적이다. 2. 쓸 수 있는 소형 모델 라인업 온디바이스용으로 변환·공개된 모델은 이미 선택지가 꽤 넓다. 대표적인 것들을 규모순으로 놓으면 이렇다. Gemma 3n E2B/E4B : 구글이 온디바이스를 겨냥해 만든 모델. 실효 파라미터 2B/4B로 동작하도록 선택적 활성화 기법을 써서, 체급 대비 메모리 부담이 작다. 텍스트 외에 이미지·오디오 입력까지 받는 멀티모달이라는 점이 특징이다. Gemma 3 1B : 텍스트 전용 경량 모델. 보급형 기기까지 커버하려면 이쪽이 무난하다. Qwen3 0.6B, SmolLM 등 : 더 가벼운 대안. 품질 기대치는 낮춰야 하지만 파이프라인 검증용으로 좋다. 이 밖에 Phi 계열, DeepSeek R1 distill 등도 온디바이스용 변환본이 공개되어 있다. 모델 파일은 MediaPi...

OBS로 코딩 강의 영상 만들기 — 화면·웹캠·자막까지 강의용 세팅

이미지
OBS 설치와 기본 녹화까지 됐다면, 다음 단계는 "강의처럼 보이는 영상"이다. 코딩 강의 영상은 일반 화면 녹화와 요구사항이 다르다. 코드가 또렷하게 읽혀야 하고, 말하는 사람이 보이면 전달력이 올라가며, 자막이 있으면 소리를 못 켜는 시청자까지 잡을 수 있다. 이번 글은 화면+웹캠+자막을 갖춘 강의용 OBS 세팅을 실제 준비 순서대로 정리한다. 강의 영상에 필요한 소스 구성 OBS의 장면(Scene) 하나에 소스(Source) 네 개를 쌓는 구성이 기본이다. 소스 목록의 위가 앞, 아래가 뒤로 겹쳐진다. 화면 캡처 : 에디터만 담을 거면 윈도우 캡처 (창 캡처), 에디터·터미널·브라우저를 오가면 디스플레이 캡처 를 쓴다. 강의는 화면 전환이 잦아서 나는 디스플레이 캡처를 기본으로 쓰고, 모니터가 두 대라면 녹화용 모니터를 하나로 고정한다. 비디오 캡처 장치 : 웹캠이다. 추가하면 화면 위에 겹쳐진다. 오디오 입력 캡처 : 마이크. 설정의 오디오 탭에서 잡혀 있으면 별도 소스는 필요 없다. 텍스트 소스 (선택): 강의 제목이나 챕터 표시용. 자막을 실시간으로 넣을 때도 텍스트 소스를 쓴다. 화면 + 웹캠 오버레이 배치 웹캠 배치는 원칙이 하나다. 코드를 가리지 않을 것 . 실제 배치 순서는 이렇다. 웹캠 소스를 선택하고 모서리를 드래그해 화면의 15~20% 크기로 줄인다. Shift를 누르고 드래그하면 비율 무시, 그냥 드래그하면 비율이 유지된다. 보통 오른쪽 아래 에 둔다. 에디터의 코드 영역은 왼쪽 위부터 채워지므로 오른쪽 아래가 가장 안전하다. 단, 터미널 출력이 화면 하단에 나오는 구성이라면 오른쪽 위로 올린다. 웹캠 소스에 우클릭 → 필터에서 필요하면 자르기(크롭)를 적용해 배경을 줄이고 얼굴 위주로 만든다. 강의 중 웹캠을 잠깐 숨겨야 하는 구간(전체 화면으로 코드를 봐야 할 때)을 위해, 웹캠이 없는 장면을 하나 더 만들어 두고 장면 전환으로 넘긴다. 소스 눈 아이콘을 끄는 것보다 실수가 적다....

Gemma 파인튜닝 첫걸음 — LoRA로 내 데이터에 맞춘 모델 만들기

이미지
로컬 LLM을 쓰다 보면 "이 모델이 내 말투로, 내 형식대로 답하면 좋겠다"는 순간이 온다. 이전 글 "로컬 LLM 제대로 활용하는 법"에서 파인튜닝을 개념으로만 다뤘는데, 이 글은 그 심화 실전편이다. Gemma를 LoRA 방식으로 가볍게 파인튜닝해서 다시 Ollama에 올려 쓰기까지의 전체 흐름을, 처음 하는 사람 기준으로 순서대로 밟는다. 결론부터 말하면 생각보다 어렵지 않고, 생각보다 만능도 아니다. 1. 파인튜닝 vs RAG — 언제 뭘 쓰나 시작 전에 방향부터 잡자. 새로운 "지식"을 넣고 싶은 거라면 파인튜닝이 아니라 RAG가 먼저다. 파인튜닝은 지식 주입에 비효율적이고, 문서가 바뀔 때마다 재학습해야 한다. 반면 말투·출력 형식·응답 규칙·도메인 특유의 문체 처럼 "태도"를 바꾸고 싶다면 파인튜닝이 맞다. 예를 들어 항상 정해진 JSON 형식으로 답하게 하거나, 고객 응대 문체를 일관되게 만들거나, 특정 분야 용어 사용 습관을 들이는 일이다. 둘은 경쟁 관계가 아니라 보완 관계라서, 지식은 RAG로 공급하고 형식은 파인튜닝으로 굳히는 조합이 실전에서 흔하다. 2. LoRA가 뭔가 — 전체 재학습과의 차이 모델의 수십억 개 파라미터를 전부 다시 학습하는 풀 파인튜닝은 개인 GPU로는 비현실적이다. LoRA(Low-Rank Adaptation)는 기존 가중치를 전부 동결해 두고, 그 옆에 붙인 작은 저랭크 행렬(어댑터)만 학습 하는 기법이다. 학습 대상 파라미터가 전체의 몇 퍼센트 수준으로 줄어들기 때문에 GPU 메모리 요구가 크게 낮아지고, 결과물도 수십~수백 MB짜리 어댑터 파일 하나로 떨어진다. 여기에 4비트 양자화를 결합한 QLoRA를 쓰면 무료 Colab의 T4 GPU로도 소형 Gemma를 학습할 수 있다. 어댑터는 본체와 분리되어 있으므로 용도별로 여러 개 만들어 갈아 끼우는 운용도 가능하다. 3. 데이터셋 준비 — 형식과 최소 규모 가장 오래...