Skip to content

필사 모드: LLM을 바닥부터 만들어보기 — 스탠퍼드 CS336 스타일 학습 로드맵

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며 — 왜 지금 from-scratch인가

2026년 상반기, 해커뉴스와 GeekNews에서 가장 꾸준히 상위권에 오르는 교육 콘텐츠가 하나 있습니다. 바로 스탠퍼드의 CS336, Language Modeling from Scratch입니다. 강의 자료와 과제가 전부 공개되어 있고, 수강생은 외부 라이브러리의 고수준 추상화 없이 토크나이저, 트랜스포머, 학습 루프, 추론 엔진을 전부 직접 구현합니다.

흥미로운 점은 타이밍입니다. 2026년은 AI 코딩 에이전트가 보편화된 해입니다. Claude Code나 Codex 같은 에이전트가 수 시간짜리 자율 작업을 처리하고, 프롬프트 엔지니어링이라는 말은 컨텍스트 엔지니어링과 루프 엔지니어링이라는 키워드로 대체되고 있습니다. 모델을 직접 만들 필요가 그 어느 때보다 없어 보이는 시대에, 오히려 바닥부터 만들어보는 강의가 폭발적인 인기를 얻고 있는 것입니다.

이 글에서는 CS336 스타일 커리큘럼을 단계별로 해부하고, 각 단계에서 무엇을 배우는지, 왜 API 시대에 이것이 중요한지, 그리고 혼자서도 따라갈 수 있는 20주 학습 플랜을 정리합니다.

전체 커리큘럼 한눈에 보기

CS336 스타일 커리큘럼은 크게 6개 축으로 구성됩니다.

+-------------+ +--------------+ +--------------+

| 1. 토크나이저 | -> | 2. 아키텍처 | -> | 3. 학습 인프라 |

| BPE 구현 | | Transformer | | 데이터/분산 |

+-------------+ +--------------+ +--------------+

|

v

+-------------+ +--------------+ +--------------+

| 6. 추론 최적화| <- | 5. 정렬 | <- | 4. 스케일링 |

| KV cache | | SFT/RLHF/DPO| | 법칙과 예산 |

+-------------+ +--------------+ +--------------+

순서가 중요합니다. 토크나이저 없이는 데이터가 없고, 아키텍처 없이는 학습할 대상이 없으며, 인프라 없이는 의미 있는 규모로 학습할 수 없습니다. 스케일링 법칙은 예산을 어디에 쓸지 알려주고, 정렬은 베이스 모델을 쓸모 있게 만들며, 추론 최적화는 만든 모델을 실제로 서빙할 수 있게 합니다.

1단계 — 토크나이저: BPE를 직접 구현하기

모든 LLM의 입구는 토크나이저입니다. CS336의 첫 과제도 BPE(Byte Pair Encoding) 토크나이저를 처음부터 구현하는 것입니다. 개념은 단순합니다. 가장 자주 등장하는 인접 바이트 쌍을 반복적으로 병합해 어휘를 만들어 나갑니다.

from collections import Counter

def get_pair_counts(corpus):

"""토큰 시퀀스 목록에서 인접 쌍 빈도를 센다."""

counts = Counter()

for tokens in corpus:

for a, b in zip(tokens, tokens[1:]):

counts[(a, b)] += 1

return counts

def merge_pair(corpus, pair, new_token):

"""corpus 전체에서 pair를 new_token으로 병합한다."""

merged = []

for tokens in corpus:

out, i = [], 0

while i < len(tokens):

if i < len(tokens) - 1 and (tokens[i], tokens[i + 1]) == pair:

out.append(new_token)

i += 2

else:

out.append(tokens[i])

i += 1

merged.append(out)

return merged

def train_bpe(text, vocab_size):

바이트 수준에서 시작: 기본 어휘 256개

corpus = [list(text.encode("utf-8"))]

merges = {}

next_id = 256

while next_id < vocab_size:

counts = get_pair_counts(corpus)

if not counts:

break

best = counts.most_common(1)[0][0]

merges[best] = next_id

corpus = merge_pair(corpus, best, next_id)

next_id += 1

return merges

이 단순한 구현을 실제 코퍼스에 돌려보면 곧바로 첫 번째 교훈을 얻습니다. 너무 느립니다. 수 기가바이트 코퍼스에서 매 병합마다 전체를 다시 스캔하면 며칠이 걸립니다. 그래서 우선순위 큐와 역인덱스로 증분 갱신을 구현하게 되고, 이 과정에서 토크나이저가 단순한 전처리가 아니라 그 자체로 시스템 엔지니어링 문제임을 체감합니다.

직접 구현하며 배우는 것들은 다음과 같습니다.

- 바이트 수준 BPE가 유니코드 문제(한국어, 이모지)를 어떻게 우회하는지

- 어휘 크기가 시퀀스 길이와 임베딩 테이블 크기에 미치는 트레이드오프

- 왜 숫자나 공백 처리 규칙 하나가 다운스트림 성능을 좌우하는지

2단계 — 트랜스포머 아키텍처: 어텐션을 코드로 이해하기

수식으로 보면 어렵게 느껴지는 셀프 어텐션도 코드로 보면 행렬 곱 몇 번입니다. 스케일드 닷프로덕트 어텐션의 본질을 PyTorch로 표현하면 이렇습니다.

class CausalSelfAttention(nn.Module):

def __init__(self, d_model, n_head):

super().__init__()

assert d_model % n_head == 0

self.n_head = n_head

self.head_dim = d_model // n_head

self.qkv = nn.Linear(d_model, 3 * d_model, bias=False)

self.proj = nn.Linear(d_model, d_model, bias=False)

def forward(self, x):

B, T, C = x.shape

q, k, v = self.qkv(x).split(C, dim=2)

(B, T, C) -> (B, n_head, T, head_dim)

q = q.view(B, T, self.n_head, self.head_dim).transpose(1, 2)

k = k.view(B, T, self.n_head, self.head_dim).transpose(1, 2)

v = v.view(B, T, self.n_head, self.head_dim).transpose(1, 2)

어텐션 점수 = Q @ K^T / sqrt(head_dim)

scores = q @ k.transpose(-2, -1) / math.sqrt(self.head_dim)

인과 마스크: 미래 토큰을 보지 못하게

mask = torch.triu(torch.ones(T, T, device=x.device), diagonal=1).bool()

scores = scores.masked_fill(mask, float("-inf"))

attn = F.softmax(scores, dim=-1)

out = attn @ v # (B, n_head, T, head_dim)

out = out.transpose(1, 2).contiguous().view(B, T, C)

return self.proj(out)

여기에 RMSNorm, SwiGLU 피드포워드, RoPE(회전 위치 임베딩)를 더하면 2026년 기준 표준 디코더 블록이 완성됩니다. 직접 만들 때 비로소 체감하는 포인트들이 있습니다.

- 인과 마스크 한 줄이 언어 모델과 인코더를 가르는 결정적 차이라는 것

- pre-norm과 post-norm의 차이가 학습 안정성에 미치는 영향

- 어텐션의 메모리 사용량이 시퀀스 길이의 제곱에 비례한다는 것을 OOM 에러로 직접 확인하는 경험

CS336은 여기서 멈추지 않고 FlashAttention의 아이디어(타일링으로 어텐션 행렬을 메모리에 만들지 않기)까지 Triton 커널로 구현하게 합니다. 이 단계에서 GPU 메모리 계층 구조에 대한 감각이 생깁니다.

3단계 — 학습 인프라: 데이터 파이프라인과 분산 학습

모델 코드는 전체 작업의 20퍼센트에 불과합니다. 나머지는 데이터와 인프라입니다.

데이터 파이프라인

웹 크롤 데이터(Common Crawl 류)를 학습 가능한 토큰 스트림으로 바꾸는 과정은 그 자체로 하나의 파이프라인입니다.

원시 HTML

| 텍스트 추출 (boilerplate 제거)

v

언어 필터링 (fastText 분류기)

|

v

품질 필터링 (휴리스틱 + 분류기)

|

v

중복 제거 (MinHash / 정확 일치)

|

v

토큰화 + 셔플 + 고정 길이 청크

|

v

학습용 바이너리 샤드 (.bin)

중복 제거 하나만 해도 MinHash LSH를 구현해야 하고, 품질 필터의 기준 하나가 최종 모델 성능을 수 퍼센트 좌우합니다. 데이터 작업이 모델 아키텍처보다 성능에 더 큰 영향을 준다는 것이 최근 수년간의 일관된 교훈입니다.

분산 학습 기초

단일 GPU를 넘어서는 순간 분산 학습이 필요합니다. 핵심 개념 세 가지만 잡으면 됩니다.

| 기법 | 무엇을 나누나 | 통신 비용 | 적합한 상황 |

| --- | --- | --- | --- |

| DDP (데이터 병렬) | 배치 | 그래디언트 all-reduce | 모델이 GPU 1장에 들어갈 때 |

| FSDP / ZeRO | 파라미터+옵티마이저 상태 | all-gather, reduce-scatter | 모델이 1장에 안 들어갈 때 |

| 텐서 병렬 | 행렬 곱 자체 | 레이어마다 all-reduce | 초대형 모델, 고속 인터커넥트 |

미니멀한 DDP 학습 루프는 다음과 같습니다.

from torch.nn.parallel import DistributedDataParallel as DDP

dist.init_process_group(backend="nccl")

rank = dist.get_rank()

torch.cuda.set_device(rank)

model = GPT(config).cuda(rank)

model = DDP(model, device_ids=[rank])

optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.1)

for step, batch in enumerate(loader):

x, y = batch

x, y = x.cuda(rank), y.cuda(rank)

logits = model(x)

loss = F.cross_entropy(logits.view(-1, logits.size(-1)), y.view(-1))

loss.backward()

torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)

optimizer.step()

optimizer.zero_grad(set_to_none=True)

직접 돌려보면 학습 곡선이 발산하는 경험을 반드시 하게 됩니다. 러닝레이트 워밍업, 그래디언트 클리핑, bf16 혼합 정밀도 같은 장치들이 왜 존재하는지 몸으로 배우는 단계입니다.

4단계 — 스케일링 법칙: 예산을 어디에 쓸 것인가

스케일링 법칙은 컴퓨트 예산이 주어졌을 때 모델 크기와 데이터 양을 어떻게 배분할지 알려주는 경험 법칙입니다. Chinchilla 논문의 핵심 결론은 파라미터 수와 학습 토큰 수를 대략 1 대 20 비율로 맞추는 것이 컴퓨트 최적이라는 것입니다.

def chinchilla_optimal(compute_budget_flops):

"""6ND 근사를 사용한 대략적인 compute-optimal 배분.

C = 6 * N * D, D = 20 * N 가정."""

C = 6 * N * (20 * N) = 120 * N^2

n_params = (compute_budget_flops / 120) ** 0.5

n_tokens = 20 * n_params

return n_params, n_tokens

예: A100 8장으로 2주 (대략 1.2e21 FLOPs 가정)

params, tokens = chinchilla_optimal(1.2e21)

print(f"params: {params/1e9:.2f}B, tokens: {tokens/1e9:.0f}B")

대략 3B 파라미터, 63B 토큰 수준

소규모 실험으로 스케일링 곡선을 직접 그려보는 것이 CS336의 백미입니다. 1M, 10M, 100M 파라미터 모델을 같은 데이터로 학습시키고 손실을 로그-로그 그래프에 찍으면 거의 직선이 나옵니다. 이 직선을 외삽해서 더 큰 모델의 성능을 예측하는 것이 프런티어 랩이 실제로 하는 일의 축소판입니다.

주의할 점은 Chinchilla 최적이 학습 컴퓨트만의 최적이라는 것입니다. 추론 비용까지 고려하면 작은 모델을 더 오래 학습시키는 것(오버트레이닝)이 총비용에서 유리한 경우가 많고, 실제로 최근 공개 모델들은 Chinchilla 비율보다 훨씬 많은 토큰으로 학습됩니다.

5단계 — 정렬: SFT, RLHF, DPO

프리트레이닝이 끝난 베이스 모델은 다음 토큰 예측기일 뿐입니다. 지시를 따르게 만들려면 정렬 단계가 필요합니다.

베이스 모델

|

v

SFT (지도 미세조정)

| 고품질 지시-응답 쌍으로 학습

v

선호 최적화 (RLHF 또는 DPO)

| 사람이 선호하는 응답 방향으로 조정

v

최종 어시스턴트 모델

- SFT는 단순합니다. 지시-응답 쌍을 만들어 일반 언어 모델 손실로 미세조정합니다. 데이터 품질이 전부입니다.

- RLHF는 보상 모델을 따로 학습한 뒤 PPO 같은 강화학습으로 정책을 최적화합니다. 강력하지만 구현 난도와 불안정성이 높습니다.

- DPO는 보상 모델과 강화학습 루프를 없애고, 선호 쌍(선택된 응답과 거절된 응답)으로 직접 정책을 최적화합니다.

DPO 손실의 핵심을 코드로 보면 다음과 같습니다.

def dpo_loss(policy_chosen_logps, policy_rejected_logps,

ref_chosen_logps, ref_rejected_logps, beta=0.1):

"""선택된 응답과 거절된 응답의 로그확률 차이를

참조 모델 대비 벌려주는 방향으로 학습한다."""

chosen_ratio = policy_chosen_logps - ref_chosen_logps

rejected_ratio = policy_rejected_logps - ref_rejected_logps

logits = beta * (chosen_ratio - rejected_ratio)

return -F.logsigmoid(logits).mean()

직접 구현해 보면 정렬이 마법이 아니라 손실 함수 설계 문제라는 것, 그리고 베이스 모델 품질과 선호 데이터 품질이 결과의 상한선을 정한다는 것을 알게 됩니다.

6단계 — 추론 최적화: KV cache부터

학습된 모델을 서빙하는 순간 전혀 다른 엔지니어링 문제가 시작됩니다. 자기회귀 생성은 토큰 하나를 만들 때마다 전체 시퀀스를 다시 계산하는 구조인데, KV cache가 이를 해결합니다.

class KVCache:

def __init__(self, batch, n_head, max_len, head_dim, device):

shape = (batch, n_head, max_len, head_dim)

self.k = torch.zeros(shape, device=device, dtype=torch.bfloat16)

self.v = torch.zeros(shape, device=device, dtype=torch.bfloat16)

self.pos = 0

def update(self, k_new, v_new):

t = k_new.size(2)

self.k[:, :, self.pos:self.pos + t] = k_new

self.v[:, :, self.pos:self.pos + t] = v_new

self.pos += t

return self.k[:, :, :self.pos], self.v[:, :, :self.pos]

캐시를 붙이면 생성 단계의 계산량이 시퀀스 길이에 대해 제곱에서 선형으로 떨어집니다. 대신 메모리를 먹습니다. 이 트레이드오프를 체감하고 나면 GQA(쿼리 그룹화)가 왜 등장했는지, vLLM의 PagedAttention이 왜 혁신이었는지가 자연스럽게 이해됩니다. 추론 최적화는 별도 글에서 더 깊게 다루겠지만, 핵심은 추론이 학습과 완전히 다른 병목(메모리 대역폭)을 가진다는 점입니다.

직접 만들 때 배우는 것 vs API 시대에 왜 중요한가

정당한 반문이 있습니다. 에이전트가 코드를 짜주는 시대에 왜 손으로 어텐션을 구현해야 할까요.

첫째, 디버깅과 의사결정의 질이 달라집니다. 컨텍스트 길이를 늘리면 비용이 왜 제곱으로 뛰는지, 왜 어떤 작업에서 토크나이저 때문에 숫자 계산이 약한지, 파인튜닝과 RAG 중 무엇을 선택할지 같은 실무 판단은 내부 구조를 아는 사람과 모르는 사람이 완전히 다르게 내립니다.

둘째, AI 에이전트를 부리는 능력 자체가 내부 이해에 비례합니다. 2026년의 핵심 역량으로 떠오른 컨텍스트 엔지니어링은 결국 모델이 컨텍스트를 어떻게 소비하는지(어텐션, 위치 임베딩, KV cache)에 대한 이해 위에서만 정교해질 수 있습니다.

셋째, 추상화는 언젠가 새기 마련입니다(leaky abstraction). API 뒤에 숨은 모델도 토크나이저 경계, 컨텍스트 한계, 샘플링 파라미터라는 형태로 내부 구조를 드러냅니다. 바닥부터 만들어본 경험은 이 누수를 만났을 때 당황하지 않게 해주는 보험입니다.

어떤 컴퓨트로 시작할까

from-scratch 학습의 진입 장벽으로 흔히 GPU 비용을 꼽지만, 단계별로 필요한 컴퓨트는 생각보다 작습니다.

| 단계 | 필요 컴퓨트 | 현실적인 선택지 | 대략 비용 |

| --- | --- | --- | --- |

| 토크나이저, 어텐션 구현 | CPU만으로 충분 | 로컬 노트북 | 무료 |

| 문자 단위 LM, 10M 모델 | GPU 1장 (8GB VRAM) | Colab 무료/Pro, 로컬 게이밍 GPU | 무료~월 2만원 |

| 100M 모델 프리트레이닝 | GPU 1장 (24GB VRAM) | 클라우드 스팟 인스턴스 | 수만 원 수준 |

| 1B급 실험, 분산 학습 | GPU 2~8장 | 시간당 과금 GPU 클라우드 | 실험당 수십만 원 |

| SFT, DPO (1B 이하) | GPU 1장 (24GB VRAM) | LoRA 활용 시 더 작게도 가능 | 수만 원 수준 |

처음 8주는 사실상 무료로 진행할 수 있습니다. 환경 구축은 다음 정도면 충분합니다.

가상환경과 핵심 의존성

python -m venv .venv

source .venv/bin/activate

pip install torch numpy tiktoken datasets wandb

nanoGPT로 첫 학습 감각 잡기

git clone https://github.com/karpathy/nanoGPT.git

cd nanoGPT

python data/shakespeare_char/prepare.py

python train.py config/train_shakespeare_char.py

학습 진행 상황은 처음부터 로깅 도구로 기록하는 습관을 들이는 것이 좋습니다. 손실 곡선, 러닝레이트, 그래디언트 노름을 매 실험마다 남겨두면 나중에 발산 원인을 추적할 때 큰 자산이 됩니다.

평가를 빼먹지 말 것

자기가 만든 모델은 객관적으로 평가해야 합니다. 최소한의 평가 셋업은 다음과 같습니다.

@torch.no_grad()

def estimate_perplexity(model, loader, max_batches=50):

model.eval()

total_loss, n = 0.0, 0

for i, (x, y) in enumerate(loader):

if i >= max_batches:

break

logits = model(x.cuda())

loss = F.cross_entropy(

logits.view(-1, logits.size(-1)), y.cuda().view(-1)

)

total_loss += loss.item()

n += 1

model.train()

return math.exp(total_loss / n)

perplexity는 같은 토크나이저를 쓰는 모델끼리만 비교 가능하다는 점에 주의해야 합니다. 어휘가 다르면 토큰당 손실의 의미 자체가 달라집니다.

20주 학습 플랜

주당 8~10시간 투자를 가정한 셀프 스터디 플랜입니다.

| 주차 | 주제 | 핵심 활동 | 산출물 |

| --- | --- | --- | --- |

| 1 | 환경 구축과 베이스라인 | PyTorch, GPU 환경, 문자 단위 LM | 문자 단위 바이그램 모델 |

| 2 | BPE 토크나이저 1 | 나이브 BPE 구현 | 동작하는 학습 코드 |

| 3 | BPE 토크나이저 2 | 우선순위 큐 최적화, 인코딩/디코딩 | 실전 속도의 토크나이저 |

| 4 | 어텐션 기초 | 단일 헤드 어텐션, 인과 마스크 | 어텐션 모듈 |

| 5 | 트랜스포머 블록 | 멀티헤드, RMSNorm, SwiGLU, RoPE | 디코더 블록 |

| 6 | 전체 모델 조립 | GPT 클래스, 가중치 초기화 | 10M 파라미터 모델 |

| 7 | 학습 루프 | AdamW, 코사인 스케줄, 클리핑 | 안정적인 학습 곡선 |

| 8 | 혼합 정밀도와 프로파일링 | bf16, torch.compile, 처리량 측정 | 토큰/초 리포트 |

| 9 | 데이터 파이프라인 1 | 텍스트 추출, 언어 필터 | 정제 스크립트 |

| 10 | 데이터 파이프라인 2 | MinHash 중복 제거, 샤딩 | 학습용 데이터셋 |

| 11 | 중간 프로젝트 | 100M급 모델 프리트레이닝 | 자체 베이스 모델 |

| 12 | 스케일링 실험 | 1M~100M 손실 곡선 적합 | 스케일링 그래프 |

| 13 | 분산 학습 1 | DDP, 멀티 GPU 학습 | 분산 학습 스크립트 |

| 14 | 분산 학습 2 | FSDP 또는 ZeRO 개념과 실험 | 메모리 사용 비교 |

| 15 | SFT | 지시 데이터 구축, 미세조정 | 지시 따르는 모델 |

| 16 | DPO | 선호 데이터, DPO 손실 구현 | 정렬된 모델 |

| 17 | 평가 | perplexity, 벤치마크, LLM 심판 | 평가 리포트 |

| 18 | 추론 최적화 1 | KV cache, 샘플링 구현 | 자체 생성 엔진 |

| 19 | 추론 최적화 2 | 배칭, 양자화 개념, 속도 측정 | 지연/처리량 리포트 |

| 20 | 최종 프로젝트 | 전체 파이프라인 정리, 블로그 작성 | 공개 저장소 + 회고 |

미니 프로젝트 아이디어

nanoGPT 류의 작고 완결된 프로젝트가 학습 효율이 가장 좋습니다.

1. **나노 셰익스피어**: 문자 단위 모델로 셰익스피어 풍 텍스트 생성. 4시간이면 끝나고 전체 그림이 잡힙니다.

2. **한국어 BPE 토크나이저**: 한국어 위키 덤프로 어휘 32k 토크나이저를 만들고 기존 토크나이저와 압축률 비교.

3. **나만의 nanoGPT 포크**: RoPE, RMSNorm, SwiGLU를 직접 추가하고 원본과 손실 곡선 비교.

4. **스케일링 미니 랩**: 3개 크기 모델로 손실 곡선을 적합하고 10배 큰 모델의 손실을 예측한 뒤 실제로 검증.

5. **DPO 실습**: 공개 선호 데이터셋으로 1B 이하 모델을 정렬하고 전후 응답을 블라인드 비교.

6. **미니 추론 서버**: KV cache와 동적 배칭을 갖춘 생성 서버를 직접 구현하고 동시 요청 처리량 측정.

함정과 비판적 시각

from-scratch 학습에도 함정이 있습니다.

- **컴퓨트 환상**: 집에서 프런티어급 모델을 만들 수는 없습니다. 목표는 작동 원리의 체화이지 SOTA 재현이 아닙니다. 100M급 모델로도 배울 것은 전부 배웁니다.

- **바퀴 재발명에 매몰**: 토크나이저 최적화에 4주를 쓰는 것은 본말전도입니다. 각 단계는 동작하는 수준에서 멈추고 다음으로 넘어가는 규율이 필요합니다.

- **프로덕션 코드와의 거리**: 교육용 구현은 단순화되어 있습니다. 실제 서빙에는 vLLM 같은 검증된 엔진을 쓰는 것이 맞습니다. 직접 구현은 그 엔진을 이해하고 튜닝하기 위한 기반입니다.

- **이력서 효과에 대한 과대평가**: from-scratch 경험 자체보다, 그 과정에서 나온 글과 코드와 측정 결과가 평가받습니다. 산출물을 공개하는 습관이 중요합니다.

마치며

LLM을 바닥부터 만들어보는 것은 2026년에도, 어쩌면 2026년이라서 더, 가치 있는 투자입니다. 에이전트가 코드를 대신 짜주는 시대일수록 시스템의 바닥을 아는 사람과 모르는 사람의 격차는 추상화 계층 아래에서 조용히 벌어집니다. CS336과 nanoGPT라는 훌륭한 공개 자료가 있으니, 20주 플랜의 1주차부터 가볍게 시작해 보시기 바랍니다. 문자 단위 모델이 그럴듯한 문장을 처음 뱉어내는 순간의 감각은 API 호출로는 절대 얻을 수 없는 종류의 것입니다.

참고 자료

- CS336 공식 페이지: https://cs336.stanford.edu/

- nanoGPT (Karpathy): https://github.com/karpathy/nanoGPT

- Karpathy의 Zero to Hero 강의: https://karpathy.ai/zero-to-hero.html

- Attention Is All You Need 논문: https://arxiv.org/abs/1706.03762

- Chinchilla 스케일링 법칙 논문: https://arxiv.org/abs/2203.15556

- DPO 논문: https://arxiv.org/abs/2305.18290

- FlashAttention 논문: https://arxiv.org/abs/2205.14135

- vLLM 공식 문서: https://docs.vllm.ai/

- Hacker News의 CS336 토론: https://news.ycombinator.com/item?id=44046428

- GeekNews: https://news.hada.io/

현재 단락 (1/259)

2026년 상반기, 해커뉴스와 GeekNews에서 가장 꾸준히 상위권에 오르는 교육 콘텐츠가 하나 있습니다. 바로 스탠퍼드의 CS336, Language Modeling from ...

작성 글자: 0원문 글자: 10,398작성 단락: 0/259