본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2026. 4. 13. · 0 Views
Day 4 학습용 샘플 데이터 만들기
LLM을 학습시키기 위한 샘플 데이터를 직접 만들어봅니다. 작은 텍스트 말뭉치를 준비하고, 토크나이저로 변환한 뒤 PyTorch 텐서로 만드는 전체 과정을 단계별로 배웁니다.
목차
- 학습 데이터란 무엇인가
- 문자 집합 구축하기
- 텍스트를 정수 시퀀스로 변환하기
- 입력과 정답 쌍 만들기
- PyTorch 텐서로 변환하기
- 학습용 미니배치 분할하기
- 전체 데이터 파이프라인 구성하기
1. 학습 데이터란 무엇인가
어느 날 김개발 씨가 박시니어 씨의 모니터를 힐끗 보게 되었습니다. 화면에는 수천 줄의 텍스트가 줄줄이 흘러가고 있었습니다.
"선배님, 이게 뭔가요?" 김개발 씨가 물었습니다. 박시니어 씨는 미소를 지으며 대답했습니다.
"LLM의 밥이야. 학습 데이터 말이야."
학습 데이터는 언어모델이 언어의 규칙과 패턴을 배우기 위해 읽어들이는 텍스트 말뭉치입니다. 마치 아이가 많은 책을 읽으며 말을 배우는 것과 같습니다.
양질의 데이터가 곧 양질의 모델을 만듭니다.
다음 코드를 살펴봅시다.
# 학습용 작은 말뭉치 준비하기
text = """
안녕하세요. 오늘 날씨가 정말 좋습니다.
내일도 날씨가 좋으면 산책을 가겠습니다.
프로그래밍은 매일 연습해야 실력이 늡니다.
파이썬은 배우기 쉬운 프로그래밍 언어입니다.
"""
# 전체 길이 확인
print(f"전체 글자 수: {len(text)}")
# 전체 글자 수: 131
김개발 씨는 어제 만든 문자 단위 토크나이저를 성공적으로 완성했습니다. 이제 토크나이저가 실제로 동작하는지 확인할 준비가 되었습니다.
하지만 그 전에 한 가지 더 필요한 것이 있었습니다. 바로 모델에게 먹여줄 학습 데이터입니다.
"LLM 바닥부터 만들기: 30일 완성 코스"의 4일 차입니다. 어제는 텍스트를 숫자로 변환하는 토크나이저를 만들었습니다.
이번에는 그 토크나이저에 넣어줄 적당한 텍스트를 준비하는 것이 오늘의 목표입니다. 학습 데이터란 무엇일까요?
쉽게 비유하자면, 학습 데이터는 학생에게 주는 교과서와 같습니다. 학생이 어떤 교과서로 공부하느냐에 따라 아는 것도 다르고, 실력도 달라집니다.
마찬가지로 언어모델도 어떤 텍스트로 학습하느냐에 따라 성능이 크게 달라집니다. 실제로 GPT-4 같은 대규모 언어모델은 인터넷 전체의 텍스트를 학습 데이터로 사용합니다.
위키백과, 뉴스 기사, 블로그 글, 코드 저장소 등 수조 개의 토큰을 읽어들입니다. 하지만 우리는 지금 작은 모델을 만들고 있으므로, 작은 데이터로 시작하는 것이 합리적입니다.
위의 코드에서는 아주 작은 샘플 텍스트를 준비했습니다. 날씨 이야기, 프로그래밍 이야기 등 간단한 문장 몇 개입니다.
실전에서는 훨씬 더 많은 텍스트가 필요하지만, 지금은 동작 원리를 이해하는 것이 우선입니다. 텍스트를 직접 작성할 수도 있고, 파일에서 불러올 수도 있습니다.
프로젝트가 커지면 텍스트 파일을 따로 관리하는 것이 좋습니다. 지금은 코드 안에 직접 넣어서 간단하게 시작해봅시다.
주의할 점이 하나 있습니다. 학습 데이터에 중복 문장이 너무 많으면 모델이 특정 패턴에 과적합될 수 있습니다.
또한 너무 짧은 텍스트로 학습하면 모델이 충분히 다양한 패턴을 배우지 못합니다. 적당한 길이와 다양성이 중요합니다.
김개발 씨는 고개를 끄덕였습니다. "그러니까 모델의 실력은 결국 데이터가 결정한다는 건가요?" 박시니어 씨는 웃으며 대답했습니다.
"맞아요. 데이터가 곧 모델의 식단이니까요."
실전 팁
💡 - 학습 데이터는 다양한 문장 구조와 어휘를 포함하는 것이 좋습니다
- 처음에는 100~1000자 정도의 작은 데이터로 시작해 동작을 확인하세요
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
2. 문자 집합 구축하기
김개발 씨가 어제 만든 토크나이저 코드를 다시 열어봤습니다. encode 함수와 decode 함수가 잘 작동하긴 했지만, 새로운 텍스트를 넣으려면 매번 문자 집합을 다시 만들어야 한다는 걸 깨달았습니다.
"이걸 좀 더 체계적으로 관리할 순 없을까요?"
**문자 집합(Vocabulary)**은 텍스트에 등장하는 모든 고유 문자의 모음입니다. 각 문자에 고유한 정수 번호를 부여하면, 컴퓨터가 텍스트를 숫자로 처리할 수 있습니다.
이 과정은 모든 NLP 작업의 첫 단추입니다.
다음 코드를 살펴봅시다.
# 학습 데이터에서 고유 문자 집합 추출
chars = sorted(set(text))
vocab_size = len(chars)
print(f"고유 문자 수: {vocab_size}")
# 고유 문자 수: 37 (한글, 영문, 공백, 특수문자 등)
# 문자 <-> 정수 매핑 딕셔너리 생성
stoi = {ch: i for i, ch in enumerate(chars)}
itos = {i: ch for i, ch in enumerate(chars)}
print(f"'안'의 번호: {stoi['안']}")
print(f"5번 문자: {itos[5]}")
어제 김개발 씨는 토크나이저의 기본 구조를 배웠습니다. 하지만 오늘은 조금 다른 관점에서 접근해보려고 합니다.
바로 학습 데이터와 토크나이저의 관계입니다. 문자 집합이란 무엇일까요?
비유하자면, 이것은 마치 도서관의 색인 카드 시스템과 같습니다. 도서관에 수만 권의 책이 있어도, 각 책에 고유한 번호가 있으면 원하는 책을 빠르게 찾을 수 있습니다.
마찬가지로 수많은 문자 중에서 고유 번호가 있어야 컴퓨터가 처리할 수 있습니다. 위 코드에서 sorted(set(text))라는 한 줄이 핵심입니다.
먼저 set(text)로 텍스트에서 중복을 제거한 뒤, sorted()로 정렬합니다. 이렇게 하면 항상 같은 순서의 문자 목록을 얻을 수 있습니다.
순서가 일관되어야 모델이 올바르게 학습할 수 있습니다. enumerate 함수는 각 문자에 0부터 시작하는 번호를 붙여줍니다.
stoi는 문자를 숫자로 바꾸는 딕셔너리이고, itos는 숫자를 문자로 바꾸는 딕셔너리입니다. 이 둘은 항상 쌍으로 존재해야 합니다.
한 가지 재미있는 점이 있습니다. 한국어 텍스트의 경우 고유 문자 수가 생각보다 많습니다.
한글 음절, 영문 알파벳, 숫자, 공백, 마침표, 줄바꿈 문자 등이 모두 각각의 문자로 인식됩니다. 이게 바로 문자 단위 토크나이제이션이 가진 한계 중 하나입니다.
박시니어 씨가 설명을 덧붙였습니다. "문자 집합의 크기, 즉 vocab_size는 모델 설계에 아주 중요해요.
이 숫자가 모델의 출력 차원을 결정하거든요." 김개발 씨는 노트에 vocab_size를 크게 적었습니다. 아직 이 숫자가 왜 중요한지는 모르지만, 분명 나중에 중요해질 것 같았습니다.
실전 팁
💡 - set()과 sorted()를 조합하면 항상 일관된 순서의 문자 집합을 얻을 수 있습니다
- stoi와 itos는 반드시 양방향 매핑이어야 encode와 decode가 모두 가능합니다
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
3. 텍스트를 정수 시퀀스로 변환하기
김개발 씨의 모니터 화면에는 이제 텍스트가 아닌 숫자들이 나타나고 있었습니다. "안녕하세요"라는 문장이 [3, 14, 27, 8, 15]처럼 변환되어 출력된 것입니다.
"이 숫자들로 어떻게 학습시킨다는 걸까요?" 김개발 씨는 혼잣말을 중얼거렸습니다.
정수 시퀀스는 텍스트를 토크나이저를 통해 정수 리스트로 변환한 결과입니다. 컴퓨터는 숫자를 다루는 데 탁월하므로, 텍스트를 숫자로 바꾸는 것이 모델 학습의 필수 전처리 과정입니다.
다음 코드를 살펴봅시다.
# 전체 텍스트를 정수 시퀀스로 인코딩
data = [stoi[ch] for ch in text]
print(f"시퀀스 길이: {len(data)}")
print(f"앞 20개 토큰: {data[:20]}")
# 특정 구간의 텍스트 복원해보기
decoded = ''.join([itos[i] for i in data[10:30]])
print(f"복원된 텍스트: {decoded}")
어제 배운 encode 함수를 떠올려보세요. 텍스트를 받아서 숫자 리스트를 반환하는 함수였죠.
오늘은 이를 전체 학습 데이터에 적용하는 방법을 알아봅니다. 리스트 컴프리헨션 [stoi[ch] for ch in text] 한 줄이 전체 텍스트를 숫자로 변환합니다.
텍스트의 각 문자를 하나씩 꺼내서 stoi 딕셔너리로 변환하고, 그 결과를 리스트에 담는 것입니다. 파이썬의 간결한 문법 덕분에 복잡한 변환이 단 한 줄로 끝납니다.
변환된 결과인 data는 이제 정수들의 리스트입니다. 컴퓨터에게 이것은 그저 숫자 나열에 불과합니다.
하지만 우리에게는 "안녕하세요. 오늘 날씨가..."라는 의미 있는 문장입니다.
중요한 점은, 모델이 배우는 것도 결국 이 숫자들 사이의 패턴이라는 사실입니다. 디코딩 과정도 간단합니다.
itos[i]로 숫자를 다시 문자로 바꾼 뒤, join()으로 이어붙이면 원래 텍스트가 복원됩니다. 인코딩과 디코딩이 완벽하게 대칭이어야 한다는 것을 기억하세요.
여기서 한 가지 생각해볼 점이 있습니다. data의 길이는 곧 학습할 수 있는 토큰의 총량입니다.
토큰이 많을수록 모델이 더 다양한 패턴을 학습할 수 있습니다. 하지만 동시에 학습 시간도 길어집니다.
적절한 데이터 크기를 선택하는 것도 실력입니다. 박시니어 씨가 화이트보드에 다이어그램을 그렸습니다.
텍스트가 화살표를 통해 숫자 리스트로 변환되고, 그 숫자 리스트가 다시 화살표를 통해 모델로 들어가는 그림이었습니다. "이게 전체 파이프라인의 뼈대야.
각 단계가 순서대로 연결되어야 해요."
실전 팁
💡 - 인코딩 후 반드시 디코딩해보세요. 원본과 일치하는지 확인하는 것이 좋은 습관입니다
- 리스트 컴프리헨션은 for문보다 빠르고 파이썬다운 방식입니다
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
4. 입력과 정답 쌍 만들기
"이 숫자들만 있으면 학습시킬 수 있는 건가요?" 김개발 씨가 물었습니다. 박시니어 씨는 고개를 가로저었습니다.
"아직 한 단계가 더 필요해요. 모델에게 '입력'과 '정답'을 나눠서 보여줘야 하거든요.
마치 학교에서 문제와 정답지를 따로 주는 것처럼요."
입력-정답 쌍은 언어모델 학습의 핵심 데이터 구조입니다. 주어진 텍스트에서 한 토큰씩 이동하며, 앞부분을 입력으로, 다음 토큰을 정답으로 구성합니다.
이것이 바로 Next Token Prediction의 실체입니다.
다음 코드를 살펴봅시다.
# x와 y 쌍 만들기 (컨텍스트 윈도우 5)
context_window = 5
x_list, y_list = [], []
for i in range(len(data) - context_window):
x = data[i:i + context_window]
y = data[i + context_window]
x_list.append(x)
y_list.append(y)
# 첫 3개 쌍 확인
for j in range(3):
print(f"x: {x_list[j]} -> y: {y_list[j]}")
print(f" '{''.join(itos[i] for i in x_list[j])}' -> '{itos[y_list[j]]}'")
1일 차에 배웠던 내용이 기억나시나요? 언어모델의 핵심 임무는 다음 토큰을 예측하는 것입니다.
"안녕하"가 주어지면 "세"를 맞추고, "안녕하세"가 주어지면 "요"를 맞추는 식입니다. 이 개념을 실제 데이터로 구현하는 것이 오늘의 핵심입니다.
쉽게 비유하자면, 이것은 마치 빈칸 뚫기 문제와 같습니다. "오늘 날씨가 ( )"에서 괄호 안에 들어갈 단어를 맞추는 것과 같은 원리입니다.
차이가 있다면, 우리는 항상 마지막 한 글자를 빈칸으로 만든다는 점입니다. context_window는 모델이 한 번에 볼 수 있는 토큰의 수입니다.
5로 설정하면, 모델은 항상 앞의 5개 토큰을 보고 6번째 토큰을 예측합니다. 윈도우 크기가 클수록 모델이 더 긴 문맥을 이해할 수 있지만, 학습 난이도도 올라갑니다.
for문 안의 슬라이싱이 핵심입니다. data[i:i+context_window]는 i번째부터 5개의 토큰을 잘라냅니다.
그리고 data[i+context_window]는 바로 그 다음 토큰, 즉 정답을 가져옵니다. 이렇게 한 칸씩 이동하면서 전체 데이터에서 모든 가능한 쌍을 만들어냅니다.
예를 들어 "안녕하세요"라는 5글자가 있다면, "안녕하" -> "세", "녕하세요" -> "?" 처럼 여러 쌍이 만들어집니다. 한 문장에서도 수많은 학습 쌍이 생겨나는 셈입니다.
이렇게 데이터를 효율적으로 재활용하는 것도 언어모델 학습의 특징입니다. 박시니어 씨가 중요한 점을 짚었습니다.
"x와 y의 길이가 다르다는 걸 주목하세요. x는 항상 context_window 길이이고, y는 항상 하나의 정수입니다.
이 asymmetry가 모델 구조를 결정해요." 김개발 씨는 노트에 x와 y의 관계를 그림으로 그렸습니다. 한 칸씩 밀어서 만드는 이 구조가 이제 눈에 들어오기 시작했습니다.
실전 팁
💡 - context_window는 보통 8~256 사이로 설정합니다. 처음에는 작게 시작해보세요
- x와 y가 한 칸 어긋나 있다는 것이 next token prediction의 핵심입니다
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
5. PyTorch 텐서로 변환하기
김개발 씨는 지금까지 파이썬 리스트로 데이터를 다뤘습니다. 하지만 박시니어 씨는 PyTorch를 사용하라고 했습니다.
"리스트로는 GPU를 활용할 수 없어요. 모델 학습을 하려면 반드시 텐서로 변환해야 합니다." 그 말에 김개발 씨는 어제 복습했던 PyTorch 기본기가 떠올랐습니다.
**PyTorch 텐서(Tensor)**는 GPU 가속 연산을 지원하는 다차원 배열입니다. 파이썬 리스트를 텐서로 변환하면, PyTorch의 자동 미분과 GPU 연산 기능을 활용할 수 있습니다.
모델 학습의 필수 조건입니다.
다음 코드를 살펴봅시다.
import torch
# 파이썬 리스트를 PyTorch 텐서로 변환
x_tensor = torch.tensor(x_list, dtype=torch.long)
y_tensor = torch.tensor(y_list, dtype=torch.long)
print(f"x 형태: {x_tensor.shape}") # [샘플 수, 5]
print(f"y 형태: {y_tensor.shape}") # [샘플 수]
print(f"x 데이터 타입: {x_tensor.dtype}") # torch.int64
# 첫 번째 샘플 확인
print(f"x[0]: {x_tensor[0]}")
print(f"y[0]: {y_tensor[0]}")
어제 PyTorch 기본기를 정리하면서 텐서를 만들어봤습니다. 오늘은 그 지식을 실제 학습 데이터에 적용해봅니다.
텐서 변환은 리스트에서 텐서로 바꾸는 단순한 작업이지만, 이 한 줄이 파이썬 세계와 딥러닝 세계를 연결하는 다리입니다. 왜 텐서가 필요할까요?
비유하자면, 파이썬 리스트는 자전거이고 PyTorch 텐서는 스포츠카입니다. 자전거로도 목적지까지 갈 수 있지만, 대량의 데이터를 빠르게 처리하려면 스포츠카가 필요합니다.
텐서는 GPU 위에서 병렬 연산을 수행할 수 있어, 리스트보다 수백 배 빠르게 동작합니다. torch.tensor() 함수가 핵심입니다.
파이썬 리스트를 받아서 텐서 객체를 생성합니다. dtype=torch.long은 64비트 정수형을 의미합니다.
토큰 인덱스는 정수이므로 실수형(float)이 아닌 정수형(long)을 사용해야 합니다. 이 구분이 중요합니다.
실수형으로 넣으면 모델이 엉뚱하게 동작합니다. 변환 후 x_tensor.shape를 확인해보면 [샘플 수, 5]라는 2차원 형태가 나옵니다.
행이 전체 학습 샘플의 수이고, 열이 컨텍스트 윈도우 크기입니다. 반면 y_tensor.shape는 [샘플 수]로 1차원입니다.
각 샘플마다 정답이 하나씩 있으니까요. 이 차원의 차이를 이해하는 것이 모델을 설계하는 데 핵심입니다.
x는 2차원, y는 1차원. 이 구조가 Transformer 모델의 입력과 출력 형태를 결정합니다.
내일 배울 내용이지만, 지금 차원을 미리 눈에 익혀두면 좋습니다. 박시니어 씨가 마지막으로 확인 사항을 알려줬습니다.
"dtype을 반드시 확인하세요. float32 텐서에 정수 인덱스를 넣으면 embedding 계층에서 에러가 나요.
이런 실수를 찾는 데 한 시간을 날린 적이 있어요." 김개발 씨는 선배의 조언을 노트에 적으며 고개를 끄덕였습니다. "dtype=torch.long, 잊지 않겠습니다."
실전 팁
💡 - 토큰 인덱스에는 항상 torch.long(int64) 타입을 사용하세요
- 텐서 변환 후 shape을 반드시 확인하는 것이 좋은 습관입니다
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
6. 학습용 미니배치 분할하기
"데이터를 다 텐서로 만들었는데요. 이걸 한 번에 모델에 넣으면 되는 건가요?" 김개발 씨가 물었습니다.
박시니어 씨는 손을 저었습니다. "데이터가 많아지면 한 번에 다 넣을 수 없어요.
조각내서 나눠줘야 해요. 이걸 미니배치라고 해요."
**미니배치(Mini-batch)**는 전체 데이터를 작은 단위로 나눈 덩어리입니다. 한 번에 전체 데이터를 처리하면 메모리가 부족하므로, 적당한 크기로 쪼개서 모델에 공급합니다.
학습의 효율성과 안정성을 동시에 얻을 수 있습니다.
다음 코드를 살펴봅시다.
import torch
# 미니배치 크기 설정
batch_size = 4
num_batches = len(x_tensor) // batch_size
# x를 (batch_size, -1) 형태로 재구성
x_batch = x_tensor[:num_batches * batch_size].view(batch_size, -1)
y_batch = y_tensor[:num_batches * batch_size].view(batch_size, -1)
print(f"x_batch 형태: {x_batch.shape}") # [4, N]
print(f"y_batch 형태: {y_batch.shape}") # [4, N]
print(f"전체 배치 수: {num_batches}")
미니배치는 딥러닝 학습에서 아주 중요한 개념입니다. 비유하자면, 이것은 마치 식당에서 주문을 처리하는 방식과 같습니다.
한 번에 100인분의 주문을 동시에 요리하면 주방이 마비되지만, 4인분씩 나눠서 요리하면 효율적으로 돌아갑니다. 미니배치도 같은 원리입니다.
batch_size = 4는 한 번에 4개의 샘플을 처리하겠다는 뜻입니다. 이 값은 GPU 메모리 크기에 따라 조절해야 합니다.
클수록 학습이 안정적이지만 메모리를 많이 차지하고, 작을수록 메모리는 적게 쓰지만 학습이 불안정해질 수 있습니다. view() 메서드가 핵심입니다.
텐서의 형태를 바꾸되, 데이터는 그대로 유지합니다. view(batch_size, -1)에서 -1은 "나머지 차원은 알아서 계산해줘"라는 뜻입니다.
PyTorch가 전체 원소 수를 batch_size로 나누어 자동으로 두 번째 차원을 계산합니다. 한 가지 주의할 점이 있습니다.
num_batches * batch_size로 슬라이싱하는 이유는, 딱 떨어지지 않는 나머지를 버리기 위해서입니다. 127개 샘플이 있고 batch_size가 4라면, 124개까지만 사용하고 마지막 3개는 버립니다.
아까워 보이지만, 이렇게 해야 텐서 형태가 깔끔하게 맞아떨어집니다. 김개발 씨가 질문했습니다.
"나머지 3개는 그냥 버리면 되나요?" 박시니어 씨는 대답했습니다. "전체 데이터가 충분히 크다면 버려도 무방해요.
보통 수만 개 이상의 샘플이 있으니까요. 하지만 데이터가 작을 때는 나머지도 활용하는 방법이 있어요.
나중에 다뤄볼게요." 실전에서는 torch.utils.data.DataLoader를 사용하지만, 지금은 원리를 이해하기 위해 직접 분할해보는 것이 좋습니다. 밑바닥부터 이해하는 것이 이 코스의 목표이니까요.
실전 팁
💡 - batch_size는 2의 거듭제곱(4, 8, 16, 32...)으로 설정하는 것이 일반적입니다
- GPU 메모리가 부족하면 batch_size를 줄이세요. OOM 에러가 발생하면 가장 먼저 확인해볼 항목입니다
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
7. 전체 데이터 파이프라인 구성하기
드디어 모든 조각이 모였습니다. 텍스트를 준비하고, 토크나이저로 변환하고, 입력-정답 쌍을 만들고, 텐서로 변환하고, 미니배치로 나누기까지.
김개발 씨는 오늘 배운 모든 것을 하나로 연결해보고 싶었습니다. "이걸 한 파일에 정리하면 완성인가요?"
데이터 파이프라인은 원시 텍스트부터 모델 입력까지의 전체 변환 과정을 하나의 흐름으로 연결한 것입니다. 각 단계가 순차적으로 연결되어야 모델이 올바르게 학습할 수 있습니다.
이 파이프라인이 곧 데이터 준비의 완성체입니다.
다음 코드를 살펴봅시다.
# 학습 데이터 파이프라인 전체 과정
import torch
# 1단계: 원시 텍스트 준비
text = "안녕하세요. 오늘은 파이썬을 배우는 날입니다."
# 2단계: 문자 집합 구축
chars = sorted(set(text))
stoi = {ch: i for i, ch in enumerate(chars)}
itos = {i: ch for i, ch in enumerate(chars)}
# 3단계: 정수 인코딩
data = [stoi[ch] for ch in text]
# 4단계: x, y 쌍 생성 (context_window=4)
ctx = 4
x = torch.tensor([data[i:i+ctx] for i in range(len(data)-ctx)])
y = torch.tensor([data[i+ctx] for i in range(len(data)-ctx)])
print(f"학습 샘플 수: {x.shape[0]}")
print(f"입력 형태: {x.shape}") # [샘플 수, 4]
print(f"정답 형태: {y.shape}") # [샘플 수]
오늘 배운 모든 것을 하나로 엮어봅시다. 비유하자면, 이것은 마치 요리 레시피의 전체 과정과 같습니다.
재료 손질(텍스트 준비)부터, 양념 만들기(문자 집합), 재료 썰기(인코딩), 그릇에 담기(x, y 쌍), 프라이팬에 올리기(텐서 변환)까지. 순서가 틀리면 요리가 망가집니다.
첫 번째 단계는 원시 텍스트 준비입니다. 파일에서 읽어올 수도 있고, 코드에 직접 작성할 수도 있습니다.
중요한 것은 텍스트가 학습에 적합한 품질이어야 한다는 점입니다. 오탈자가 많거나 의미가 없는 텍스트는 모델의 성능을 떨어뜨립니다.
두 번째 단계에서는 어제 만든 토크나이저의 핵심 부분을 재사용합니다. set()으로 고유 문자를 추출하고, 딕셔너리로 매핑을 만듭니다.
이 매핑은 학습과 추론 모두에서 사용되므로 반드시 저장해두어야 합니다. 세 번째 단계에서 텍스트가 숫자로 변환됩니다.
리스트 컴프리헨션 한 줄로 전체 변환이 끝납니다. 네 번째 단계에서 context_window를 기준으로 입력 x와 정답 y를 분리합니다.
마지막으로 torch.tensor()로 텐서 변환을 완료합니다. 박시니어 씨가 만족스러운 표정을 지었습니다.
"이 파이프라인 하나만 제대로 이해해도 데이터 준비의 80%는 끝난 거예요. 나머지는 데이터 크기를 키우고, 전처리를 추가하는 정도예요." 김개발 씨는 오늘 하루 종일 만든 이 코드를 data_pipeline.py 파일로 저장했습니다.
작지만 완성된 파이프라인. 내일은 드디어 이 데이터를 실제 모델에 넣어볼 예정입니다.
실전 팁
💡 - 데이터 파이프라인은 별도 파일로 분리하여 관리하면 재사용하기 좋습니다
- 각 단계 후에 shape과 dtype을 출력하여 데이터가 올바르게 변환되었는지 확인하세요
- 내일 배울 Baseline 모델에서 이 파이프라인이 바로 사용됩니다. 오늘 완성한 코드를 꼭 저장해두세요
- 이 카드뉴스는 "LLM 바닥부터 만들기: 30일 완성 코스" 코스의 4/30편입니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
프레임워크 선택 LangGraph vs CrewAI vs AutoGen 완벽 가이드
AI 에이전트 개발을 위한 세 가지 핵심 프레임워크를 비교 분석합니다. 각 프레임워크의 특징, 장단점, 실무 선택 기준을 초급 개발자도 이해할 수 있도록 설명합니다.
Day 6 학습 루프 이해하기
LLM이 실제로 어떻게 학습하는지 학습 루프의 핵심 원리를 단계별로 살펴봅니다. Forward Pass, Loss 계산, Backward Pass, 파라미터 업데이트까지 한 사이클의 전 과정을 이해합니다.
Day 5 Baseline 모델 만들기
복잡한 모델에 앞서 가장 단순한 Baseline 모델을 직접 만들어봅니다. 아무런 기교 없이 순수하게 다음 토큰을 예측하는 모델을 구현하면서, 언어모델의 가장 기본 구조를 이해합니다.
Day 2 PyTorch 기본기 정리
LLM을 직접 만들기 위해 꼭 알아야 할 PyTorch의 핵심 개념을 정리합니다. 텐서, 자동 미분, 옵티마이저까지 모델 학습의 기초를 다집니다.
LLM 핵심 원리 함수 호출 환각 임베딩 완벽 가이드
LLM의 세 가지 핵심 개념인 함수 호출(Function Calling), 환각(Hallucination), 임베딩(Embedding)을 중급 개발자 관점에서 실무 중심으로 설명합니다. 에이전트 AI 엔지니어가 반드시 알아야 할 원리와 실전 팁을 담았습니다.