콘텐츠로 이동

실제 검증 기록

2026-10-11: GPU 대여 추천 추가 (Zhichuan Cloud 초대 링크)

검사 실제 결과
내용 홈 페이지에 "GPU 대여: 저자가 쓰는 Zhichuan Cloud"를 추가했습니다. 3.1절에 "어디서 빌릴까"(가격, 신규 사용자 쿠폰, 인스턴스 선택, 데이터 디스크와 미러 소스 사용 경험)를 추가했고, 0.4절 준비 표의 계정 행과 예산 행을 위안화(RMB) 예시로 바꿨습니다. 모두 초대 링크와 초대 코드 zt4f01m0를 포함하며, 저자의 초대 링크임을 밝히고 쿠폰 수령 규칙을 설명합니다
가격 출처 사용자가 제공한 2026-10-11 페이지 스크린샷: RTX 4090D 24 GB 종량제 ¥1.25/시간, 일 단위 ¥29, 주 단위 ¥200, 월 단위 ¥800. 초대 규칙은 사용자가 제공한 초대 페이지 스크린샷에서 가져왔습니다. gpuhome.cc는 클라이언트 렌더링 페이지라 내장 브라우저에서 빈 화면으로 열려 직접 확인하지 못했습니다
회귀 테스트 / 전자책 106 passed. mkdocs build --strict 통과, 52개 페이지와 27,728개 링크·리소스 검사 통과
가격 스크린샷 사용자가 제공한 대여 페이지 스크린샷을 images/gpuhome-rtx4090d-price-2026-10-11.png로 변환해 홈 페이지와 3.1절 가격 표 아래에 넣었습니다

2026-10-11: 홈 페이지에 저자 소개 추가, 대상 독자를 ML 비전공 개발자로 변경

검사 실제 결과
내용 홈 페이지에 "저자 소개"(약력, X, 위챗 공식 계정, 샤오훙슈, QR 코드 두 개)를 추가했습니다. 홈 페이지, 튜토리얼 도입부, README, 사이트 설명, CLAUDE.md의 대상 독자를 "ML을 하지 않지만 LoRA 파인튜닝을 처음부터 배우고 싶은 개발자"로 바꿨습니다. 1장 제목과 "백엔드 비유"를 일반적인 개발 비유로 바꿨습니다
이미지 images/author-wechat-qrcode.jpg. 샤오훙슈 QR 코드는 명함 스크린샷에서 잘라 images/author-xiaohongshu-qrcode.jpg로 저장했습니다. book/build.py는 이제 images/ 아래의 PNG와 JPG 파일을 모두 게시합니다
회귀 테스트 / 전자책 106 passed. mkdocs build --strict 통과, 52개 페이지와 27,716개 링크·리소스 검사 통과. 로컬 미리보기를 눈으로 확인했고 데스크톱과 휴대폰 폭에서 레이아웃에 문제가 없었습니다

2026-10-11: 노트북 13절을 curl 호출로 변경

검사 실제 결과
내용 노트북 13절에서 Python 예시를 빼고 curl 5묶음으로 바꿨습니다: 헬스 체크, 최소 요청, 학습 형식의 요청(system = 역할 + 학년 구간 + 팩트 카드), 멀티턴, 스트리밍. 튜토리얼 5.5절에도 같은 "먼저 curl로 직접 호출하기"를 추가했고, 기존 Python 및 SDK 예시는 그대로 두었습니다
요청 본문 JSON 파일 두 개는 build_messages로 생성합니다. Qwen 토크나이저로 계산한 싱글턴 요청의 prompt_tokens는 395입니다. 이 머신에서 heredoc을 bash로 실제 실행했고, 생성된 파일은 모두 유효한 JSON이었습니다
테스트 test_tutorial.py에 curl 테스트를 추가했습니다: 모델 이름이 --served-model-name과 일치, temperature=0, 스트리밍 예시 포함, 파일 속 messages가 build_messages 출력과 완전히 동일. Python 호출 예시는 이제 plan.md에서 읽어 실행합니다. 106 passed
전자책 / 번들 mkdocs build --strict 통과, 52개 페이지와 27,708개 링크·리소스 검사 통과. GPU 업로드 번들을 다시 생성했습니다
아직 확인하지 않음 실제 vLLM 서버에서의 curl 응답

2026-10-11: RTX 4090에서 첫 1 Epoch 전체 학습 (사용자가 GPU 호스트에서 실측)

검사 실제 결과
환경 RTX 4090 24 GB(드라이버 580.119.02, 최대 CUDA 13.0). 이미지 2.7.1-CUDA12.6-Py3.11-Ubuntu22. 공식 PyTorch 인덱스에 접근할 수 없어 중국 국내 미러에서 torch를 설치했습니다
로딩 NF4 베이스 모델을 불러온 뒤 nvidia-smi에 4353 MiB가 표시되었습니다
학습 runs/science-002, 72/72 step, 소요 시간 26:19. 평균 학습 loss 2.233. step별 학습 loss 처음/마지막 5.813 → 1.55
검증 loss step 12/24/36/48/60/72: 2.506 / 2.186 / 2.034 / 1.976 / 1.961 / 1.960. Mean Token Accuracy 0.462 → 0.573
실패에서 얻은 교훈 그 전에 두 번, 커널을 재시작하지 않고 학습 셀을 다시 실행해 이미 학습된 모델 위에서 학습이 이어졌습니다. 학습 loss는 약 0.5까지 떨어졌고 검증 loss는 2.3으로 다시 올라갔습니다(과적합). runs/science-001은 삭제했습니다
문서 곡선 스크린샷을 images/loss-curve-rtx4090-2026-10-11.png로 저장해 4.5절에 구간별 해설과 함께 넣었습니다. book/build.py는 이제 images/ 아래의 모든 PNG를 게시합니다
아직 확인하지 않음 8단계 완료 기록(최대 VRAM, adapter 파일), LoRA를 끈 베이스 모델의 검증 loss, 10단계 답변 비교, 병합과 vLLM

2026-10-10: 공식 PyTorch 인덱스에 접근할 수 없을 때의 Alibaba Cloud 미러 대체 경로

검사 실제 결과
발단 GPU 호스트에서 pip install torch==2.8.0 --index-url https://download.pytorch.org/whl/cu126을 실행하자 Network is unreachable로 실패했습니다(사용자의 실제 출력)
미러 확인 개발 머신에서 mirrors.aliyun.com/pytorch-wheels를 조회했습니다: cu126 디렉터리에 torch-2.8.0+cu126-cp311-manylinux_2_28_x86_64가 있고, cu129 디렉터리에 vLLM 0.21.0이 요구하는 torch 2.11.0, torchaudio 2.11.0, torchvision 0.26.0의 cp311 Linux 패키지가 있습니다(의존성 버전은 PyPI의 vLLM 0.21.0 메타데이터 기준). GPU 호스트에서 미러로 실제 설치해 보지는 않았습니다
문서 3.3절, 5.4절, 노트북 배포 셀, GPU_UPLOAD_README.md에 -f https://mirrors.aliyun.com/pytorch-wheels/... 대체 명령을 추가했습니다. GPU 업로드 번들을 다시 생성했습니다(파일 31개, 3.89 MiB)
회귀 테스트 / 전자책 105 passed. mkdocs build --strict 통과, 52개 페이지와 27,600개 링크·리소스 검사 통과

2026-10-10: 3.3절에서 업로드 번들 내용 설명

검사 실제 결과
내용 3.3절에 패키징 명령과 "업로드 번들에 들어 있는 것"을 추가했습니다: unzip -l이 실제로 나열한 파일 31개를 바탕으로 디렉터리 트리와 용도를 적고, 번들에 없는 것과 그 출처를 따로 정리했습니다. requirements-train.txt 주석의 옛 절 번호를 3.1로 바꿨습니다
번들 tools/build_gpu_zip.py로 다시 생성: 파일 31개, 3.89 MiB
회귀 테스트 / 전자책 105 passed. mkdocs build --strict 통과, 52개 페이지와 27,594개 링크·리소스 검사 통과

2026-10-10: 2장 후반부 간소화

검사 실제 결과
내용 2.4절에 "멀티턴 대화는 여러 번 학습되는가?"와 멀티턴 히스토리가 쌓이는 방식을 추가했습니다. 기존 2.6–2.11을 2.6 일곱 단계 돌아보기, 2.7 데이터 수정과 교체, 2.8 선택 사항인 로컬 검사로 바꿨습니다. 중복된 관찰 질문 설명은 삭제했고(4.5절에 이미 있음), 검토 요구 사항은 6.1절로, CLI 스냅샷 설명은 4.6절로, few-shot 선택 설명은 6.4절로 옮겼습니다. 관련 절 번호 참조도 함께 갱신했습니다
회귀 테스트 105 passed(튜토리얼에서 중복된 예시 명령 lab.prepare/lab.audit 두 개가 빠졌지만, 모든 CLI에 여전히 예시가 하나 이상 있습니다)
전자책 mkdocs build --strict 통과. 52개 페이지와 27,561개 로컬 링크·리소스 검사 통과

2026-10-10: "팩트 카드가 왜 필요한가" 추가

검사 실제 결과
내용 2.2절에 "팩트 카드가 왜 필요한가: 자주 나오는 세 가지 질문"(베이스 모델이 이미 상식을 아는데 왜 카드가 필요한가, 카드는 입력이지 학습 목표가 아니므로 학습 후 모델이 기억하리라 기대할 수 없다는 점, 학습할 때도 왜 반드시 넣어야 하는가)을 추가하고 data/README.md도 맞췄습니다. 0.1절과 2.5절에 이 내용을 가리키는 안내를 넣었고, 2.1절 표 아래에 "그래도 val 세트가 필요한 이유"를 추가했습니다
회귀 테스트 107 passed
전자책 mkdocs build --strict 통과. 52개 페이지와 27,594개 로컬 링크·리소스 검사 통과. 로컬 미리보기를 눈으로 확인했고 2장의 인용 블록과 비교 표가 제대로 표시되었습니다

2026-10-10: dataset.json을 train/val/test 나란히 배치로 변경 (schema 4)

검사 실제 결과
데이터 변환 최상위가 facts, train, val, test 네 개의 나란한 배열이 되었습니다. 대화에서 split 필드를 제거했고 내용은 바뀌지 않았습니다. lab.data --allow-draft --formal은 {'train': 500, 'val': 50, 'test': 50}을 출력합니다
읽기 로직 lab.data.tag_splits가 속한 배열에 따라 메모리에서 split을 붙입니다. 옛 episodes 레이아웃과 자체 split을 가진 대화는 모두 오류를 냅니다. validate, prepare, infer는 바뀌지 않았습니다
CLI 스냅샷 고정된 Qwen 토크나이저로 lab.prepare --allow-draft --formal 실행: 파일 9개, train 1150개와 val 115개 SFT 샘플. val.episodes.jsonl의 대화 50개는 모두 split: val입니다
문서 2.2절에 "팩트 카드는 무엇에 쓰이고 어디서 사용되는가"(검증, 프롬프트 조립, 노트북, 스냅샷, A/B/C 추론, 블라인드 평가, 배포 호출)를 추가했습니다. data/README.md, README, GPU 업로드 안내도 맞췄습니다
회귀 테스트 107 passed(새 테스트 세 개: 나란히 배치 레이아웃, 옛 레이아웃 거부, 노트북 D1 읽기)
전자책 mkdocs build --strict 통과. 52개 페이지와 27,571개 로컬 링크·리소스 검사 통과. GPU 업로드 번들을 다시 생성했습니다(파일 31개, 3.88 MiB)

2026-10-10: 장 순서 재배치, "심화 및 참고" 접기 블록 제거

검사 실제 결과
구조 기존 0–13장을 0–8장 + 부록으로 통합했습니다: 0 목표와 준비(새로 쓴 전체 흐름, 두 머신의 협업 방식, 준비 체크리스트), 1 개념, 2 학습 데이터(기존 3–5장), 3 GPU, 4 학습, 5 배포, 6 품질 평가(기존 8–9장), 7 비용·문제 해결·인수 확인, 8 개발자 참고(기존 11장과 13장). 사이드바는 한 단계의 평평한 목차가 되었고, 본문의 접기 블록은 일반 소절이 되었습니다
새 설명 2–6장은 각각 "이 장 한눈에 보기" 상자(할 일 / 준비물 / 결과물 / 소요 시간)로 시작합니다. 2.5절에 고정된 Qwen 토크나이저로 실제 렌더링한 day-night-01:0(408 토큰, 지도 대상 22 토큰)을 추가했습니다. 4.1절에서 step 하나 안에서 일어나는 일을 설명합니다. 5장은 API 요청 경로를 그린 도식으로 시작합니다
참조 갱신 plan.md, 노트북, README, GPU_UPLOAD_README, todo.md, book/README.md의 장 번호를 새 번호로 갱신했습니다. GPU 업로드 번들을 다시 생성했습니다(파일 31개, 3.88 MiB)
회귀 테스트 103 passed
전자책 mkdocs build --strict 통과. 52개 페이지와 28,089개 로컬 링크·리소스 검사 통과. 로컬 미리보기를 눈으로 확인했고 0, 2, 4, 5장의 도식과 한눈에 보기 상자가 제대로 표시되었습니다

2026-10-04: 배포 학습 중심 개편

검사 실제 결과
학습량 노트북이 샘플 수로부터 step 수를 계산합니다: train 샘플 1150개 ÷ 누적 16 → 72 step(1 Epoch). val 샘플 115개에 대한 eval loss(12 step마다)와 loss-curve.png를 추가했습니다
데이터 정리 문자열 이어 붙이기로 남은 반각 공백을 답변 662개에서 제거했습니다. increase_depth_when_requested, ask_for_evidence_without_blame, explain_then_invite_exploration 답변을 각각 60개씩 다시 썼습니다. lab.data --allow-draft --formal 통과
실제 토큰화 고정된 Qwen 토크나이저로 다시 생성: train 1150개, val 115개. 최장 550 토큰, 평균 459 토큰, 평균 지도 대상 36 토큰
CLI 초안 게이트 lab.train --allow-draft로 epoch 비교를 실행할 수 있고, manifest에 draft가 기록됩니다. 후보 동결과 테스트 세트 추론은 여전히 검토된 데이터를 요구합니다
배포 장 10장에 KV 캐시 추정(토큰당 144 KiB), 파라미터 설명, adapter 마운트, OpenAI SDK 스트리밍 호출, vllm bench serve 부하 테스트, 서비스 투입 체크리스트를 추가했습니다
호출 예시 로컬 API 예시는 이제 build_messages를 사용하므로 프롬프트가 학습과 일치합니다. 여전히 test_tutorial.py가 임시 HTTP 서버를 상대로 실행합니다
GPU 업로드 번들 새 tools/build_gpu_zip.py로 생성: 파일 31개, 약 3.88 MiB, 가중치 없음. 출력이 남아 있는 노트북은 패키징을 거부합니다
회귀 테스트 103 passed(아주 작은 CPU 모델로 실행한 노트북의 eval 셀과 loss 곡선 셀 포함)
전자책 mkdocs build --strict 통과. 57개 페이지와 28,387개 로컬 링크·리소스 검사 통과. 주 내비게이션을 학습 경로 → 개념 → GPU → 학습 → 배포로 바꿨습니다

| 입문자 가독성 (2026-10-08) | 2장을 8개 절로 된 단계적 개념 강의(모델 디렉터리, 구체적인 토큰 예시, loss 값에 대한 직관, diff에 빗댄 LoRA, 일곱 개 라이브러리의 역할 분담)로 다시 썼습니다. 6장에 nvidia-smi/드라이버/CUDA 절과 Jupyter 조작 표를 추가했습니다. 4장의 거버넌스 내용은 심화 자료로 접어 두었습니다. 노트북의 모든 코드 셀에 "실행하면 보이는 것"과 파라미터별 표(BitsAndBytesConfig, generate, LoraConfig, SFTConfig)를 추가했습니다. 노트북의 예상 출력 값은 추정치이며 실제 GPU 실행으로 확인해야 합니다 |

이번 라운드에서도 RTX 4090에서는 실행하지 않았습니다. 72 step의 실제 소요 시간과 VRAM, vLLM 0.21의 기동 로그, vllm bench serve의 파라미터와 결과는 모두 GPU 호스트에서의 실측을 기준으로 합니다.

2026-09-29: 초등 과학 탐구, 학습 대화 500개

검사 실제 결과
유일한 편집 가능 데이터 소스 data/dataset.json: 팩트 카드 60장. train 500, val 50, test 50. 대화당 2–3턴
범위 다섯 분류 각각 100/10/10개 대화. train은 1–2, 3–4, 5–6학년에 각각 167, 167, 166개 대화
생성 방법 학습 주제 50개마다 교육 경로 10개. 지식, 오개념, 비유의 한계, 관찰, 후속 질문을 주제별로 작성한 뒤 완전한 대화로 조합했습니다. 같은 주제 안에서 일부 답변이 재사용되므로, 500개의 독립된 지식 문제는 아닙니다
데이터 상태 모두 synthetic/draft. 카드 35장은 참고 출처를 읽은 기록이 있고, 25장은 아직 pending으로 표시되어 있습니다. 개별 사실 하나하나, 어린이 가독성, 실제 탐구 효과는 모두 아직 검토 대기 중입니다
지도 학습 수 train 답변 타깃 1150개, val/test 각 115개. 학습은 train만 골라 씁니다
참고 카드 독립성 사실을 독립된 요약으로 다시 썼고, 대응하는 사실 text 안에 assistant 타깃이 통째로 그대로 들어 있는 경우는 발견되지 않았습니다. 이것이 모든 의미적 유사성을 배제한다는 뜻은 아닙니다
실제 토큰화와 마스킹 고정된 Qwen 토크나이저와 실제 TRL collator로 1150/1150개 샘플이 통과했고, 최장 553 토큰입니다. 첫 샘플은 408 토큰이며 그중 지도 대상 위치가 22개입니다
데이터 스냅샷 최종본은 data/processed/science-v3에 대응하며 자동 생성 파일 9개입니다. v1/v2는 이번 라운드 정리 과정의 옛 스냅샷이며, 정식 사용 시에는 소스 데이터에서 prepare를 다시 실행해야 합니다
입력과 격리 grade_band는 프롬프트에 들어가고 behavior/review/source_url은 들어가지 않습니다. 같은 주제와 같은 사실은 split을 넘나들 수 없고, 미래의 질의응답은 새어 들어갈 수 없습니다
평가 프로토콜 B/C는 같은 입력을 유지합니다. few-shot 예시는 세 학년 구간을 모두 포함하도록 우선 고르며 train에서만 가져옵니다. 블라인드 평가는 학년 구간을 유지하고, bootstrap은 주제별로 클러스터링하며, 각 평가 세트에는 독립 주제가 5개뿐입니다
노트북과 튜토리얼 46셀 / 코드 셀 16개, 출력 비어 있음, 셀마다 설명 포함. 과학 관찰 질문, 데이터 설명, 정식 비교, vLLM 및 중국어 API 예시가 동기화되어 있습니다
실험 디렉터리 새 시나리오의 기본값은 runs/science-001이며, 옛 시나리오의 lesson/gpu 디렉터리와 혼동하지 않도록 했습니다
회귀 테스트 101 passed, 10 warnings. 아주 작은 CPU LoRA의 갱신/저장/다시 불러오기/병합, 튜토리얼 API 요청과 히스토리 전달 포함
공개 범위 이번 라운드에서는 실제 4B CUDA 학습이나 vLLM을 실행하지 않았고, 어린이 대상 연구도 하지 않았습니다. 로컬 검사로는 LoRA가 전체 프롬프트 기준선보다 낫다는 것을 증명할 수 없습니다

전자책과 GPU ZIP의 최종 빌드와 일관성 검사는 이번 라운드의 납품과 함께 완료했습니다. 아래는 모두 과거 버전 기록이며, 옛 시나리오와 옛 수치는 현재 데이터를 나타내지 않습니다.

2026-09-29: 단일 파일 데이터와 D1–D7 사용 설명

검사 실제 결과
데이터 통합 data/dataset.json에 원래의 팩트 카드 10장, 대화 30개, 참조 답변 60개와 모든 메타데이터를 담았습니다. 이전 전후의 객체가 완전히 같으며, 중복된 소스 JSONL 파일 두 개는 삭제했습니다
주 진입점 노트북은 단일 파일을 직접 읽어 메모리에서 샘플을 만들며 processed 디렉터리에 의존하지 않습니다. D1–D7은 읽기, 필터링, 컨텍스트, 타깃, trainer, labels, 저장 위치를 표시합니다
학습 내용 실제 고정 Qwen 토크나이저로 노트북의 샘플 생성 셀을 실행했습니다. 60개의 prompt/completion/input_ids/completion_mask가 모두 옛 seed-v2와 일치합니다. 첫 샘플은 여전히 302 토큰이며 지도 대상 위치가 53개입니다
유출 방지 테스트로 val/test가 학습에 들어가지 않고, 현재 타깃과 미래 턴이 프롬프트에 들어가지 않으며, 히스토리가 올바르게 유지됨을 확인했습니다. 출처 URL과 검토 필드는 모델 입력으로 쓰이지 않습니다
회귀 테스트 95 passed, 0 skipped, 10 warnings. 실제 아주 작은 CPU LoRA 학습, 저장, 다시 불러오기, 병합, 튜토리얼 API 예시가 통과했습니다
노트북 형식 nbformat 검증 통과, 46셀 / 코드 셀 16개. 모든 코드 셀 아래에 설명이 있고, 납품 시 출력은 비어 있습니다
실험 재확인 학습 전에 메모리의 데이터를 runs/<실험 이름>/dataset.json에 저장하고, 그 사본의 SHA-256을 manifest에 기록합니다. 평소에는 data/dataset.json만 편집합니다
CLI data/prepare를 --input data/dataset.json으로 바꿨습니다. 심화 실험은 필요할 때 스냅샷을 생성합니다. 과거의 seed-v1/v2와 runs는 남겨 두었습니다
업로드 번들 파일 31개, 약 3.82 MiB. 소스 데이터는 한 부만 들어 있고 processed의 중간 파일은 없습니다. 압축 해제 후 대화 30개와 학습 타깃 60개를 확인했고, 파일이 소스와 바이트 단위로 동일합니다
경량 CLI Torch가 없는 .venv-data에서 --input으로 단일 파일 데이터를 준비했습니다. 생성된 샘플 60개가 옛 스냅샷과 일치하며, 이어서 실제 TRL collator의 mask/EOS/padding 검사가 통과했습니다
전자책 엄격 빌드 통과. 54개 페이지와 5,987개 로컬 링크·리소스 검사 통과. 데이터 페이지는 완전한 대화 하나와 그것이 참조하는 사실을 보여 주며, 옛 두 파일 방식의 소스 페이지는 제거했습니다

10개의 경고는 여전히 아주 작은 모델의 PEFT config 경로와 체크포인트 타임스탬프 정렬에서 나옵니다. 이번 라운드에서는 RTX 4090에서의 실제 4B CUDA 학습이나 vLLM 서비스를 실행하지 않았습니다. 데이터와 로컬 코드 검증은 모델 품질 향상을 의미하지 않습니다.

아래는 이전 버전의 기록입니다. 옛 데이터 진입점과 파일 수는 이 절을 기준으로 합니다.

2026-09-29: 전자책, 노트북, 코드의 최종 대응 확인

검사 실제 결과
전체 회귀 91 passed, 0 skipped, 10 warnings. 실제 노트북의 아주 작은 학습 실행과 튜토리얼 API 예시의 로컬 HTTP 검사 포함
튜토리얼 명령 README, 데이터 설명, 본문의 lab.* 명령이 모두 대응하는 실제 CLI 파서를 통과합니다. 남아 있는 모든 CLI에 실행 가능한 예시가 있습니다
진입점과 설명 13장이 현존 모듈과 항목별로 대응합니다. 심화 학습 환경으로의 전환과 A/B/C의 데이터 및 프롬프트 차이를 보완했습니다. 노트북과 10장의 배포/호출 코드가 블록 단위로 일치합니다
소스 동기화 학습 부록이 실제 학습 모듈 두 개와 일치합니다. 빌드 시 옛 자동 생성 소스 페이지와 다운로드 사본을 제거합니다
정리 lab/client.py와 그 옛 테스트를 삭제했습니다. 대신 교재의 표준 라이브러리 API 예시를 직접 테스트합니다. 정식 비교, 블라인드 평가, 재개, 내보내기에 아직 쓰이는 CLI는 남겨 두었습니다
다운로드 버전 Hugging Face에서 처음 다운로드할 때 더 새로운 revision을 받을 수 있던 문제를 고쳤습니다. 세 다운로드 소스 모두 튜토리얼의 고정 버전을 쓰며, 옛 버전 디렉터리는 몰래 다시 쓰이지 않습니다
실제 데이터 고정된 Qwen 토크나이저와 TRL collator로 seed-v2를 다시 검사했습니다. 60/60개 샘플에서 지도 범위, EOS, padding이 통과했습니다
GPU 업로드 번들 파일 38개, 약 3.85 MiB로 갱신했습니다. 압축 해제 후 동결 데이터에서 학습 샘플 60개를 얻을 수 있으며, 옛 클라이언트는 제거했습니다
전자책과 배포 번들 엄격 빌드 통과. 55개 페이지와 4,880개 로컬 링크·리소스 통과. GPU ZIP의 소스 파일 37개와 일반 소스 ZIP의 파일 53개가 현재 파일과 바이트 단위로 대응합니다. 일반 소스 ZIP은 압축 해제 후 독립적으로 빌드되고 링크 검사를 통과합니다
문서 코드 조각 Bash 블록 32개, Python 블록 3개, JSON 블록 10개가 문법 검사를 통과했습니다. SSH 터널의 주소/포트 자리표시자는 본문 지시대로 바꾼 뒤 검사했으며, 원격 호스트에는 접속하지 않았습니다

위 내용은 로컬에서 검증할 수 있는 대응 관계입니다. 10개의 경고는 아주 작은 모델의 PEFT config 경로와 체크포인트 타임스탬프 정렬에서 나옵니다. RTX 4090에 연결하지 않았으므로, 이것으로 실제 4B 다운로드, CUDA/NF4 학습, 품질 검토, vLLM 서비스가 통과했다고 주장할 수 없습니다. GitHub Pages 워크플로도 이번 라운드에서는 게시하지 않았습니다.

아래 기록은 이전 버전에 해당합니다. 파일 수, 진입점, 테스트 수는 이 절을 기준으로 합니다.

2026-09-29: 교육용 노트북 재작성과 중국 국내 다운로드

검사 실제 결과
전체 회귀 51 passed, 0 skipped, 10 warnings. 로컬 포트 테스트는 리스닝이 허용된 환경에서 실행했습니다
노트북 형식 공식 nbformat 검증 통과. 44셀, 그중 Python 코드 셀 15개. 셀마다 아래에 용도와 이유가 있고, 납품 시 출력은 비어 있습니다
노트북 실제 코드 실제 코드 셀을 추출해 아주 작은 Qwen3 CPU 모델로 LoRA 설정, TRL 지도 검사, 학습 두 step, 저장, 다시 불러오기, 생성, 병합, 전체 모델 다시 불러오기를 실행했습니다. 다시 불러온 logits가 일치하고, 병합된 logits는 허용 오차 내에서 일치합니다
디바이스 경계 CPU 테스트는 CUDA 디바이스/정밀도 설정만 바꿉니다. 학습을 명령 반환값으로 흉내 내지 않습니다. PEFT 로드 디바이스를 명시적으로 고정해 CPU 병합이 자동으로 GPU로 옮겨지지 않게 했고, CLI 병합도 같은 방식으로 고쳤습니다
다운로드 소스 ModelScope 1.34.0으로 config/토크나이저 파일 9개를 실제로 다운로드했고, 각각 SHA-256이 고정된 HF revision과 일치합니다. 실제 Qwen 토크나이저 지문이 seed-v2와 일치합니다
가중치 접근성 safetensors 샤드 세 개에서 각각 64바이트를 읽었고 모두 HTTP 206을 반환했습니다. Content-Range의 전체 크기가 동결 manifest와 일치합니다. 전체 8 GB 가중치는 다운로드하지 않았습니다
다운로드 실패 보호 부분적인 로컬 캐시, 같은 크기의 손상 파일, 원격 버전 변경, 토크나이저 변경, 버전 잠금 보호, 미러 엔드포인트, 오프라인 무결성 검사를 테스트합니다
전자책 6장은 환경과 중국 국내 다운로드를 다루고, 7장은 직접 학습에 대응하며, 10장은 내보내기, vLLM, 로컬 싱글턴/멀티턴 호출을 설명합니다. 엄격 빌드와 로컬 링크 검사 통과
업로드 번들 파일 39개, 약 3.85 MiB. 압축 해제 후 동결 샘플 60개가 완전하고, 노트북/코드/다운로드 잠금과 의존성이 동기화되어 있습니다. 환경, 캐시, 전체 가중치, 학습 결과는 들어 있지 않습니다
정리 옛 노트북 서브프로세스 보조 모듈, 선택 워크플로 스위치, 결과 ZIP 자동 패키징을 삭제했습니다. 정식 평가, 학습 재개 등 튜토리얼에서 아직 쓰는 CLI는 남겨 두었습니다

참고 자료: ModelScope 모델 저장소, vLLM 0.21 GPU 설치, IPython 커널 등록. 사용자가 제공한 Zhihu 글은 보안 인증이 걸려 본문을 읽지 못했습니다. 미러 엔드포인트는 SDK와 공식 문서로 확인했으며, 글 전체를 읽었다고 주장하지 않습니다.

10개의 경고는 아주 작은 모델의 PEFT config 경로와 체크포인트 타임스탬프 정렬에서 나옵니다. 테스트 중 PEFT의 기본 자동 디바이스 배치가 CPU 병합을 CPU 밖으로 옮긴다는 것을 발견했고, 이제 디바이스를 명시적으로 지정해 전체 회귀가 통과합니다. 사용자의 RTX 4090에는 연결하지 않았습니다. 실제 4B 다운로드, CUDA/NF4 학습, 품질 검토, vLLM 서비스는 아직 그 호스트에서 실행하지 않았습니다. vLLM은 별도 환경을 쓰므로, 먼저 호스트 드라이버가 CUDA 12.9를 지원하는지 확인하세요.

아래는 이전 버전의 과거 기록입니다. 옛 노트북 워크플로는 이번 재작성으로 대체되었습니다.

2026-09-29: GPU 노트북과 튜토리얼 진입점

검사 실제 결과
전체 회귀 테스트 46 passed, 0 skipped, 6 warnings. 노트북 서브프로세스 중단 정리, 오류 반환, 출력 보호, 파일 문법, 다운로드 일관성, audit 결과만 있을 때 패키징 거부에 대한 새 검사
노트북 형식 notebooks/01_gpu_train.ipynb가 공식 nbformat 검증을 통과했습니다. 33셀(코드 셀 18개). 납품 파일의 실행 카운트와 출력은 비어 있습니다
셀 흐름 실제 로컬 Jupyter 커널에서 기본 워크플로와 모든 선택 워크플로를 모의 명령 결과로 실행했습니다. 호출 인자는 실제 CLI 파서로 검증했고, 결과 읽기, 답변의 HTML 이스케이프, ZIP 백업이 통과했습니다. 설치, 다운로드, GPU 연산은 모두 테스트 대역을 사용했습니다
전자책 6장은 노트북을 주 진입점으로 삼고, 7장과 10장이 대응하는 단계를 제공합니다. 엄격 빌드와 로컬 링크 검사가 통과했고, 노트북 다운로드 파일이 소스 파일과 일치합니다
GPU 업로드 번들 llm-lora-tutorial-gpu.zip을 파일 37개, 약 3.84 MiB로 갱신했습니다. ZIP 무결성, 압축 해제 후 import, 동결 학습 샘플 60개 검사가 통과했습니다. 노트북과 그 실행 보조 모듈이 들어 있고, 전체 가중치나 로컬 환경은 없습니다

사용자 스크린샷에 나온 "token-audit.json만 있어도 결과 ZIP이 생성될 수 있다"는 문제를 재현해 13단계를 고쳤습니다. 이제 A/B/C 답변, 10 step 학습 기록, adapter 파일을 먼저 확인한 뒤에야 패키징을 허용합니다. 기본 워크플로와 선택 워크플로가 로컬 커널 모의 검사를 다시 통과했고 GPU 업로드 번들도 갱신했습니다. 사용자 머신에 있는 기존 노트북은 따로 동기화해야 합니다.

이번 라운드에서는 사용자의 RTX 4090에 연결하지 않았고, 4B 전체 가중치를 다운로드하지 않았으며, 실제 GPU 학습도 실행하지 않았습니다. 노트북 워크플로 모의 실행과 CPU 초소형 학습 회귀로는 로컬에서 확인 가능한 부분만 검증할 수 있습니다. 실제 CUDA, NF4, VRAM, 소요 시간, 학습 품질은 여전히 GPU에서 실행한 기록을 기준으로 합니다. 6개의 경고는 기존의 아주 작은 모델 저장과 체크포인트 타임스탬프 정렬에서 나옵니다. HTTP 테스트는 로컬 임시 포트가 허용된 환경에서 완료했습니다.

2026-09-26: 데이터와 튜토리얼 간소화

검사 실제 결과
전체 회귀 테스트 38 passed, 0 skipped, 6 warnings. 새 데이터 번들과 옛 데이터 번들, 누락된 세트, 데이터 탐색 페이지, 기존의 아주 작은 학습 검사 포함
경량 데이터 환경 .venv-data를 만들고 requirements-data.txt에 따라 Transformers 4.57.3과 Jinja2 3.1.6 및 그 의존성을 설치했습니다. torch, trl, peft, datasets, accelerate가 설치되지 않았음을 확인했습니다
경량 환경에서의 데이터 준비 대화 30개와 학습 샘플 60개를 생성했습니다. manifest에 있는 파일 5개가 전체 CPU 환경에서 생성한 seed-v2와 바이트 단위로 동일합니다
데이터 번들 구조 새 schema=2는 총 6개 파일입니다. 옛 seed-v1의 파일 13개는 남겨 두었고 무결성 검사를 통과합니다
데이터와 지도 학습 소스 데이터 내용은 그대로입니다. 실제 Qwen 토크나이저와 TRL collator로 60/60개 샘플이 통과했고, 리포트는 runs/token-audit-v2.json에 있습니다
책 속 예시 고궁 박물관 예시는 실제 첫 레코드에서 가져왔습니다. palace-01:0은 총 302 토큰이며, 컨텍스트 위치 249개와 지도 대상 위치 53개입니다
문서 코드 README, 튜토리얼, 데이터 설명에 있는 Bash 블록 30개, Python 블록 2개, 삽입된 Python 조각 1개, JSON 블록 10개가 문법 검사를 통과했습니다. 학습 코드 부록이 소스와 일치합니다
전자책 빌드 mkdocs build --strict 통과. HTML 페이지 51개와 로컬 링크·리소스 4192개 검사 통과
브라우저 검사 데스크톱과 390px 휴대폰 폭에서 데이터 장을 확인했습니다. 긴 JSON은 자동 줄바꿈되고 가로 넘침이 없으며 EOS 필드가 완전히 표시됩니다. 소스 데이터 페이지는 용도와 첫 레코드를 먼저 보여 주고, 전체 원문은 기본적으로 접혀 있습니다

첫 경량 실행에서 채팅 템플릿에 Jinja2가 없다는 것을 발견했고, 의존성을 추가한 뒤 준비에 성공했습니다. 모델 연산 라이브러리가 없다는 Transformers의 경고는 이 환경에서 예상된 것이며, 토큰화와 템플릿 렌더링은 모두 동작합니다. HTTP 테스트는 로컬 임시 포트가 허용된 환경에서 완료했습니다. 샌드박스의 리스닝 제한을 테스트 건너뛰기로 처리하지 않았습니다.

6개의 경고는 아주 작은 모델의 저장 config와 체크포인트 타임스탬프 정렬에서 나오며, 이전 검증과 같은 종류입니다. 이번에는 데이터 처리, CPU 학습 메커니즘, 책의 웹 페이지만 검증했습니다. 4B GPU 학습은 실행하지 않았고, 검토를 통과한 후보 대화도 없습니다.

2026-09-23: 첫 검증 기록

첫 실행 기록을 아래에 남겨 둡니다.

환경

  • 로컬 Darwin 25.3.0 arm64, Python 3.11.15.
  • 테스트는 임시 격리 환경 /tmp/beijing-lora-env를 사용했으며, 시스템 Python은 건드리지 않았습니다.
  • Torch 2.8.0, Transformers 4.57.3, TRL 0.24.0, PEFT 0.18.0, Accelerate 1.11.0, Datasets 4.3.0, pytest 8.4.2.
  • uv pip check로 설치된 패키지 52개가 통과했습니다. 이것은 bitsandbytes가 없는 Mac CPU 환경이므로, Linux CUDA 조합이 연동 확인되었다고 주장할 근거가 되지 않습니다.

실행한 항목

검사 결과
전체 python -m pytest -q tests 27 passed, 0 skipped, 6 warnings, 이번에는 약 3.92초
CLI 진입점 download/data/prepare/audit/train/infer/evaluate/merge/client 9개 모두 --help 성공
Python 문법 모든 lab 및 tests 파일 파싱 통과
튜토리얼 정적 검사 Bash 코드 블록 31개의 문법, 완전한 Python 코드 블록 2개, JSON 예시 1개, 모든 로컬 Markdown 링크 통과
원본 데이터 카드 10장, 대화 30개, 타깃 답변 60개, 다섯 분류 각 6개 대화. 모두 draft
실제 Qwen 토크나이저 고정 revision. config와 토크나이저를 다운로드했으며 4B 가중치는 받지 않았습니다
데이터 준비 seed-v1, train=대화 30개, 전개된 샘플 60개. val/test는 비어 있음
실제 TRL collator 감사 60/60개 지도 범위가 정확하고 EOS가 정확히 하나. 길이가 다른 샘플 두 개를 함께 넣어 padding 검사
토큰 길이 전체 길이 285–382. 타깃 지도 길이 18–54(EOS 포함). 현재 시드 기준이며 정식 데이터의 추정치가 아닙니다
아주 작은 모델 학습 무작위로 초기화한 매우 작은 Qwen3로 실제 Torch/PEFT/TRL을 사용해 두 step을 실행했고, LoRA 파라미터만 바뀌었습니다
아주 작은 모델 재개와 병합 총 4 step 계획, step 2에서 저장. 4까지 재개. 다시 불러온 logits 일치, 병합된 logits는 허용 오차 내에서 일치
HTTP 클라이언트 임시 로컬 서버로 히스토리, 정상 응답, 503, 오류 구조, 잘못된 JSON을 검증했습니다. 타임아웃 경계도 테스트했습니다
평가와 무결성 블라인드 평가 짝짓기, 누락된 점수, 동점, 대화별 클러스터링. adapter config를 바꾸면 지문이 바뀜. 수정된 준비 결과는 거부됨

모델 revision: cdbee75f17c01a7cc42f958dc650907174af0554.

토크나이저 지문: 5cc703e3e68312a345b0aa88aed16fd37eb4ca2d871900402275514280124405.

현재 로컬의 상세 기록은 runs/token-audit.json과 data/processed/seed-v1/manifest.json에 있으며, 다시 만들 수 있는 생성 파일입니다. 코드 수정 중에 만든 중간 CPU 데이터 번들은 임시 디렉터리로 옮겼고, 최종 seed-v1은 현재 프롬프트 코드로 다시 빌드했습니다.

테스트 중 겪은 문제

  • HTTP 테스트는 처음에 샌드박스의 리스닝 제한 때문에 실패했습니다. 로컬 포트가 허용된 환경에서 다시 실행해 통과했으며, 테스트를 삭제하거나 건너뛰지 않았습니다.
  • 대화가 하나뿐일 때 폭이 0인 불확실성 구간으로 표시되던 문제를 고쳤습니다. 대화가 두 개 미만이면 빈 구간을 반환합니다.
  • adapter 지문에 파라미터 파일과 config를 모두 포함해, alpha만 바꾸고도 동결 검사를 통과하는 일이 없게 했습니다.
  • 모델 파일 해시는 스트리밍 읽기를 사용해, 수 GB 샤드를 RAM에 추가로 복사하지 않습니다.
  • 6개의 경고는 무작위의 아주 작은 모델에 사전 학습 config 경로가 없다는 점과, 빠르게 저장된 체크포인트의 파일 타임스탬프를 믿을 수 없다는 점에서 나옵니다. 체크포인트를 숫자 step 순으로 정렬한 뒤 재개에 성공했으며, 이 경고들은 숨기지 않았습니다.

아직 실행하지 않았으므로 통과했다고 주장할 수 없는 항목

  • 대화 30개에 대한 대화별 사람/독립 검토. 현재 approved 대화는 없습니다.
  • 카드 30장, 정식 대화 150개로의 확장과 검토.
  • 4B 모델 가중치 다운로드, Linux CUDA/bitsandbytes 연동 확인, 실제 QLoRA.
  • GPU 10 step 스모크 테스트, 샘플 20개 과적합, 1 Epoch, r8/r16 비교.
  • 실제 생성 품질, 사실 뒷받침 비율, 블라인드 평가 승률, GPU VRAM/시간/비용.
  • 실제 4B BF16 병합, vLLM 이미지 pull/기동, 실제 모델 API와 부하.

CPU 초소형 모델 테스트는 4B 실험을 대신하지 못합니다. 항목을 하나 완료할 때마다 해당 로그/결과를 첨부하고 todo를 갱신하세요. 실제로 실행하지 않은 지표는 비워 둡니다.