From 3d044b44d1f8f3dd8d9726a576834acd8d58fb34 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:07:34 +0000 Subject: [PATCH 1/2] Add Korean documentation for BitNet This commit introduces three new files: 1. README_ko.md: A Korean translation of the original README.md. 2. Pretrain-Tuning.md: A document in Korean outlining methods and considerations for pretraining BitNet language models, with a focus on Korean language data. It highlights that BitNet models are trained from scratch with ternary weights. 3. SFT-Tuning.md: A document in Korean detailing Supervised Fine-Tuning (SFT) techniques for Korean BitNet models, including dataset preparation and the training process. These documents aim to provide you with essential information about understanding, pretraining, and fine-tuning BitNet models. --- Pretrain-Tuning.md | 82 +++++++++++ README_ko.md | 337 +++++++++++++++++++++++++++++++++++++++++++++ SFT-Tuning.md | 87 ++++++++++++ 3 files changed, 506 insertions(+) create mode 100644 Pretrain-Tuning.md create mode 100644 README_ko.md create mode 100644 SFT-Tuning.md diff --git a/Pretrain-Tuning.md b/Pretrain-Tuning.md new file mode 100644 index 00000000..34f0ba60 --- /dev/null +++ b/Pretrain-Tuning.md @@ -0,0 +1,82 @@ +# 한국어 BitNet 언어 모델 사전 학습 및 튜닝 가이드 + +## 서론 + +BitNet은 최근 주목받고 있는 1비트 대규모 언어 모델(LLM) 아키텍처로, 기존 부동소수점(FP16/BF16) 모델에 비해 메모리 사용량, 에너지 소비, 추론 속도 면에서 상당한 이점을 제공하는 것을 목표로 합니다. 본 문서는 한국어 BitNet 언어 모델, 특히 BitNet b1.58 변형을 사전 학습하는 방법에 대한 핵심 개념과 일반적인 지침을 제공합니다. + +BitNet 모델, 특히 BitNet b1.58은 가중치를 -1, 0, 1의 세 가지 값으로 표현하는 3진 가중치(ternary weights)를 특징으로 합니다. 이러한 접근 방식은 모델의 크기를 크게 줄이고 계산 효율성을 향상시킵니다. + +**매우 중요한 점:** BitNet 모델은 기존의 FP16 또는 BF16 정밀도를 가진 사전 학습된 모델을 양자화하여 얻는 것이 아닙니다. **BitNet 모델은 처음부터(from scratch) 학습되어야 합니다.** 이는 BitNet 아키텍처의 고유한 특성을 최대한 활용하고 최적의 성능을 달성하기 위해 필수적입니다. + +## BitNet b1.58 사전 학습의 핵심 특징 + +BitNet b1.58 모델을 효과적으로 사전 학습하기 위해 이해해야 할 몇 가지 주요 특징이 있습니다. + +### 1. 3진 가중치 (Ternary Weights: -1, 0, 1) + +BitNet b1.58의 핵심은 대부분의 가중치를 -1, 0, 또는 1로 제한하는 것입니다. 이는 모델의 저장 공간을 극적으로 줄이고, 곱셈 연산을 단순한 덧셈/뺄셈 또는 무시(0일 경우)로 대체하여 계산 속도를 높일 수 있는 잠재력을 가집니다. + +### 2. 처음부터 학습 (Training from Scratch) + +다시 한번 강조하지만, BitNet 모델은 기존에 학습된 FP16/BF16 모델을 단순히 양자화하는 방식으로 생성되지 않습니다. 대신, 모델 아키텍처와 학습 과정 자체가 1비트 또는 1.58비트 가중치를 염두에 두고 설계되어 처음부터 학습됩니다. 이를 통해 모델은 저정밀도 가중치 환경에 최적화될 수 있습니다. + +### 3. 전체 정밀도 `lm_head` (Full-Precision `lm_head`) + +일반적으로 BitNet 모델의 대부분의 레이어는 3진 가중치를 사용하지만, 최종 언어 모델 헤드(`lm_head` 또는 출력 레이어)는 전체 정밀도(예: FP16 또는 BF16)로 유지됩니다. 이는 모델이 미묘한 출력 분포를 더 잘 학습하고 표현하는 데 도움이 되어 전반적인 성능 저하를 최소화하는 데 기여합니다. + +### 4. 목표: 효율성과 성능의 균형 + +BitNet 사전 학습의 궁극적인 목표는 전체 정밀도 모델과 비슷한 수준의 언어 이해 및 생성 능력을 달성하면서도, 추론 시 훨씬 낮은 지연 시간(latency), 더 적은 메모리 사용량, 그리고 감소된 에너지 소비를 실현하는 것입니다. + +## 한국어 데이터 고려 사항 + +한국어 BitNet 모델을 성공적으로 사전 학습하려면 방대하고 품질 좋은 한국어 텍스트 코퍼스가 필수적입니다. + +### 1. 코퍼스 규모 및 품질 + +모델의 성능은 학습 데이터의 규모와 질에 크게 좌우됩니다. 다양한 주제와 스타일을 포괄하는 수십억 토큰 규모의 데이터셋을 목표로 해야 합니다. 데이터는 철자 오류, 문법적 오류, 불일치성 등을 최소화하기 위해 신중하게 정제되어야 합니다. + +### 2. 데이터 소스 + +* **뉴스 기사:** 시사적인 내용과 정제된 문장을 제공합니다. +* **도서:** 다양한 어휘와 문체, 깊이 있는 내용을 포함합니다. +* **웹 텍스트:** 블로그, 포럼, 웹사이트 등에서 수집된 광범위한 주제의 텍스트입니다. 다만, 정제 과정이 중요합니다. +* **학술 자료:** 전문 용어와 논리적인 글쓰기 스타일을 학습하는 데 도움이 됩니다. +* **대화 데이터:** 채팅, 메신저 대화 등은 모델의 자연스러운 대화 능력을 향상시킬 수 있습니다. + +데이터 수집 시 저작권 및 개인정보 보호 규정을 준수하는 것이 중요합니다. + +## 학습 과정 개요 + +BitNet 모델의 구체적인 학습 레시피는 공식 BitNet 논문 및 관련 간행물에서 더 자세히 찾아볼 수 있지만, 일반적인 사전 학습 과정은 다음과 같은 요소들을 포함합니다. + +### 1. 토큰화 (Tokenization) + +한국어의 특성(교착어, 띄어쓰기 등)을 잘 처리할 수 있는 토큰화 방식이 필요합니다. SentencePiece, BPE (Byte Pair Encoding) 또는 WordPiece와 같은 서브워드 토큰화 방법론을 기반으로 한국어에 맞게 학습된 토크나이저를 사용하는 것이 일반적입니다. 토크나이저의 어휘 크기는 모델 성능과 효율성에 영향을 미치므로 신중하게 결정해야 합니다. + +### 2. 학습 목표 (Training Objectives) + +표준적인 대규모 언어 모델의 학습 목표가 BitNet 사전 학습에도 적용될 수 있습니다: + +* **인과적 언어 모델링 (Causal Language Modeling, CLM):** 다음 토큰을 예측하는 방식입니다. GPT 계열 모델에서 주로 사용됩니다. +* **마스크 언어 모델링 (Masked Language Modeling, MLM):** 입력 텍스트의 일부 토큰을 마스킹하고, 모델이 이를 예측하도록 학습합니다. BERT 계열 모델에서 사용됩니다. + +BitNet의 경우, 특정 학습 목표나 변형이 제안될 수 있으므로 관련 연구를 참고하는 것이 좋습니다. + +### 3. 모델 아키텍처 + +트랜스포머(Transformer) 아키텍처를 기반으로 하되, BitNet의 3진 가중치를 적용하기 위한 수정된 레이어 구현이 필요합니다. 여기에는 사용자 정의 커널이나 연산 최적화가 포함될 수 있습니다. + +### 4. 최적화 및 하이퍼파라미터 + +AdamW와 같은 표준적인 옵티마이저가 사용될 수 있지만, 학습률(learning rate), 배치 크기(batch size), 학습 스케줄(learning rate schedule) 등은 BitNet의 특성과 사용되는 데이터셋에 맞게 조정되어야 합니다. 저정밀도 가중치 학습을 위한 특별한 정규화(regularization) 기법이나 학습 안정화 전략이 필요할 수도 있습니다. + +### 5. 계산 리소스 (Computational Resources) + +대규모 언어 모델의 사전 학습은 상당한 계산 리소스(GPU 또는 TPU)를 필요로 합니다. BitNet은 추론 시 효율성을 목표로 하지만, 사전 학습 과정 자체는 여전히 많은 연산 능력과 시간을 소모할 수 있습니다. 분산 학습(distributed training) 환경 구축이 일반적입니다. + +## 결론 + +한국어 BitNet 언어 모델의 사전 학습은 기존 LLM과는 다른 독특한 고려 사항, 특히 "처음부터 학습" 원칙과 3진 가중치 시스템을 중심으로 이루어집니다. 고품질의 대규모 한국어 코퍼스, 적절한 토큰화, 그리고 BitNet 아키텍처에 맞는 학습 전략을 통해 효율적이면서도 강력한 한국어 1비트 LLM을 개발할 수 있을 것입니다. + +본 문서는 개괄적인 지침을 제공하며, 실제 구현 및 최적의 성능을 위해서는 공식 BitNet 간행물에서 제공하는 구체적인 학습 방법론과 실험 결과를 참조하는 것이 중요합니다. diff --git a/README_ko.md b/README_ko.md new file mode 100644 index 00000000..dacfb91a --- /dev/null +++ b/README_ko.md @@ -0,0 +1,337 @@ +# bitnet.cpp +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) +![version](https://img.shields.io/badge/version-1.0-blue) + +[BitNet Model on Hugging Face](https://huggingface.co/microsoft/BitNet-b1.58-2B-4T) + +[데모](https://bitnet-demo.azurewebsites.net/)를 통해 직접 체험해 보거나, 자체 [CPU](https://github.com/microsoft/BitNet?tab=readme-ov-file#build-from-source) 또는 [GPU](https://github.com/microsoft/BitNet/blob/main/gpu/README.md)에서 빌드하고 실행해 보세요. + +bitnet.cpp는 1비트 LLM(예: BitNet b1.58)을 위한 공식 추론 프레임워크입니다. CPU 및 GPU에서 1.58비트 모델의 **빠르고** **손실 없는** 추론을 지원하는 최적화된 커널 제품군을 제공합니다(NPU 지원은 곧 제공될 예정입니다). + +bitnet.cpp의 첫 번째 릴리스는 CPU에서의 추론을 지원하는 것입니다. bitnet.cpp는 ARM CPU에서 **1.37배**에서 **5.07배**의 속도 향상을 달성하며, 모델이 클수록 성능 향상 폭이 커집니다. 또한 에너지 소비를 **55.4%**에서 **70.0%**까지 줄여 전반적인 효율성을 더욱 높입니다. x86 CPU에서는 **71.9%**에서 **82.2%**의 에너지 절감과 함께 **2.37배**에서 **6.17배**의 속도 향상을 보입니다. 또한 bitnet.cpp는 단일 CPU에서 100B BitNet b1.58 모델을 실행하여 사람의 읽기 속도(초당 5-7 토큰)에 필적하는 속도를 달성함으로써 로컬 장치에서 LLM을 실행할 수 있는 잠재력을 크게 향상시킵니다. 자세한 내용은 [기술 보고서](https://arxiv.org/abs/2410.16144)를 참조하십시오. + +m2_performance +intel_performance + +>테스트된 모델은 bitnet.cpp의 추론 성능을 보여주기 위해 연구 환경에서 사용된 더미 설정입니다. + +## 데모 + +Apple M2에서 BitNet b1.58 3B 모델을 실행하는 bitnet.cpp 데모: + +https://github.com/user-attachments/assets/7f46b736-edec-4828-b809-4be780a3e5b1 + +## 새로운 소식: +- 2025년 5월 20일 [BitNet 공식 GPU 추론 커널](https://github.com/microsoft/BitNet/blob/main/gpu/README.md) ![NEW](https://img.shields.io/badge/NEW-red) +- 2025년 4월 14일 [Hugging Face의 BitNet 공식 2B 파라미터 모델](https://huggingface.co/microsoft/BitNet-b1.58-2B-4T) +- 2025년 2월 18일 [Bitnet.cpp: 3진 LLM을 위한 효율적인 엣지 추론](https://arxiv.org/abs/2502.11880) +- 2024년 11월 8일 [BitNet a4.8: 1비트 LLM을 위한 4비트 활성화](https://arxiv.org/abs/2411.04965) +- 2024년 10월 21일 [1비트 AI 인프라: 파트 1.1, CPU에서의 빠르고 손실 없는 BitNet b1.58 추론](https://arxiv.org/abs/2410.16144) +- 2024년 10월 17일 bitnet.cpp 1.0 출시. +- 2024년 3월 21일 [1비트 LLM의 시대__학습 팁_코드_FAQ](https://github.com/microsoft/unilm/blob/master/bitnet/The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ.pdf) +- 2024년 2월 27일 [1비트 LLM의 시대: 모든 대규모 언어 모델은 1.58비트](https://arxiv.org/abs/2402.17764) +- 2023년 10월 17일 [BitNet: 대규모 언어 모델을 위한 1비트 트랜스포머 확장](https://arxiv.org/abs/2310.11453) + +## 감사의 말 + +이 프로젝트는 [llama.cpp](https://github.com/ggerganov/llama.cpp) 프레임워크를 기반으로 합니다. 오픈 소스 커뮤니티에 기여해주신 모든 저자분들께 감사드립니다. 또한 bitnet.cpp의 커널은 [T-MAC](https://github.com/microsoft/T-MAC/)에서 개척된 조회 테이블 방법론을 기반으로 구축되었습니다. 3진 모델을 넘어선 일반적인 저비트 LLM의 추론에는 T-MAC 사용을 권장합니다. + +## 공식 모델 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
모델파라미터CPU커널
I2_STL1TL2
BitNet-b1.58-2B-4T2.4Bx86
ARM
+ +## 지원되는 모델 +❗️**bitnet.cpp의 추론 기능을 보여주기 위해 [Hugging Face](https://huggingface.co/)에서 사용 가능한 기존 1비트 LLM을 사용합니다. bitnet.cpp의 출시가 모델 크기 및 학습 토큰 측면에서 대규모 설정에서 1비트 LLM 개발에 영감을 주기를 바랍니다.** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
모델파라미터CPU커널
I2_STL1TL2
bitnet_b1_58-large0.7Bx86
ARM
bitnet_b1_58-3B3.3Bx86
ARM
Llama3-8B-1.58-100B-tokens8.0Bx86
ARM
Falcon3 제품군1B-10Bx86
ARM
Falcon-E 제품군1B-3Bx86
ARM
+ +## 설치 + +### 요구 사항 +- python>=3.9 +- cmake>=3.22 +- clang>=18 + - Windows 사용자의 경우 [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)를 설치하십시오. 설치 프로그램에서 최소한 다음 옵션을 켜십시오 (CMake와 같은 필요한 추가 도구도 자동으로 설치됨): + - C++를 사용한 데스크톱 개발 + - Windows용 C++ CMake 도구 + - Windows용 Git + - Windows용 C++ Clang 컴파일러 + - LLVM 도구 집합(clang)에 대한 MS-Build 지원 + - Debian/Ubuntu 사용자의 경우 [자동 설치 스크립트](https://apt.llvm.org/)로 다운로드할 수 있습니다. + + `bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"` +- conda (강력 권장) + +### 소스에서 빌드 + +> [!IMPORTANT] +> Windows를 사용하는 경우 다음 명령에 대해 항상 VS2022용 개발자 명령 프롬프트/PowerShell을 사용해야 합니다. 문제가 발생하면 아래 FAQ를 참조하십시오. + +1. 저장소 복제 +```bash +git clone --recursive https://github.com/microsoft/BitNet.git +cd BitNet +``` +2. 종속성 설치 +```bash +# (권장) 새 conda 환경 만들기 +conda create -n bitnet-cpp python=3.9 +conda activate bitnet-cpp + +pip install -r requirements.txt +``` +3. 프로젝트 빌드 +```bash +# 수동으로 모델을 다운로드하고 로컬 경로로 실행 +huggingface-cli download microsoft/BitNet-b1.58-2B-4T-gguf --local-dir models/BitNet-b1.58-2B-4T +python setup_env.py -md models/BitNet-b1.58-2B-4T -q i2_s + +``` +
+usage: setup_env.py [-h] [--hf-repo {1bitLLM/bitnet_b1_58-large,1bitLLM/bitnet_b1_58-3B,HF1BitLLM/Llama3-8B-1.58-100B-tokens,tiiuae/Falcon3-1B-Instruct-1.58bit,tiiuae/Falcon3-3B-Instruct-1.58bit,tiiuae/Falcon3-7B-Instruct-1.58bit,tiiuae/Falcon3-10B-Instruct-1.58bit}] [--model-dir MODEL_DIR] [--log-dir LOG_DIR] [--quant-type {i2_s,tl1}] [--quant-embd]
+                    [--use-pretuned]
+
+추론 실행을 위한 환경 설정
+
+선택적 인수:
+  -h, --help            이 도움말 메시지를 표시하고 종료합니다.
+  --hf-repo {1bitLLM/bitnet_b1_58-large,1bitLLM/bitnet_b1_58-3B,HF1BitLLM/Llama3-8B-1.58-100B-tokens,tiiuae/Falcon3-1B-Instruct-1.58bit,tiiuae/Falcon3-3B-Instruct-1.58bit,tiiuae/Falcon3-7B-Instruct-1.58bit,tiiuae/Falcon3-10B-Instruct-1.58bit}, -hr {1bitLLM/bitnet_b1_58-large,1bitLLM/bitnet_b1_58-3B,HF1BitLLM/Llama3-8B-1.58-100B-tokens,tiiuae/Falcon3-1B-Instruct-1.58bit,tiiuae/Falcon3-3B-Instruct-1.58bit,tiiuae/Falcon3-7B-Instruct-1.58bit,tiiuae/Falcon3-10B-Instruct-1.58bit}
+                        추론에 사용되는 모델
+  --model-dir MODEL_DIR, -md MODEL_DIR
+                        모델을 저장/로드할 디렉터리
+  --log-dir LOG_DIR, -ld LOG_DIR
+                        로깅 정보를 저장할 디렉터리
+  --quant-type {i2_s,tl1}, -q {i2_s,tl1}
+                        양자화 유형
+  --quant-embd          임베딩을 f16으로 양자화
+  --use-pretuned, -p    미리 조정된 커널 매개변수 사용
+
+## 사용법 +### 기본 사용법 +```bash +# 양자화된 모델로 추론 실행 +python run_inference.py -m models/BitNet-b1.58-2B-4T/ggml-model-i2_s.gguf -p "당신은 도움이 되는 어시스턴트입니다" -cnv +``` +
+usage: run_inference.py [-h] [-m MODEL] [-n N_PREDICT] -p PROMPT [-t THREADS] [-c CTX_SIZE] [-temp TEMPERATURE] [-cnv]
+
+추론 실행
+
+선택적 인수:
+  -h, --help            이 도움말 메시지를 표시하고 종료합니다.
+  -m MODEL, --model MODEL
+                        모델 파일 경로
+  -n N_PREDICT, --n-predict N_PREDICT
+                        텍스트 생성 시 예측할 토큰 수
+  -p PROMPT, --prompt PROMPT
+                        텍스트를 생성할 프롬프트
+  -t THREADS, --threads THREADS
+                        사용할 스레드 수
+  -c CTX_SIZE, --ctx-size CTX_SIZE
+                        프롬프트 컨텍스트 크기
+  -temp TEMPERATURE, --temperature TEMPERATURE
+                        온도, 생성된 텍스트의 무작위성을 제어하는 하이퍼파라미터
+  -cnv, --conversation  채팅 모드 활성화 여부 (지시 모델용).
+                        (이 옵션을 켜면 -p로 지정된 프롬프트가 시스템 프롬프트로 사용됩니다.)
+
+ +### 벤치마크 +모델을 제공하여 추론 벤치마크를 실행하는 스크립트를 제공합니다. + +``` +usage: e2e_benchmark.py -m MODEL [-n N_TOKEN] [-p N_PROMPT] [-t THREADS] + +추론 실행을 위한 환경 설정 + +필수 인수: + -m MODEL, --model MODEL + 모델 파일 경로. + +선택적 인수: + -h, --help + 이 도움말 메시지를 표시하고 종료합니다. + -n N_TOKEN, --n-token N_TOKEN + 생성된 토큰 수. + -p N_PROMPT, --n-prompt N_PROMPT + 텍스트를 생성할 프롬프트. + -t THREADS, --threads THREADS + 사용할 스레드 수. +``` + +각 인수에 대한 간략한 설명은 다음과 같습니다. + +- `-m`, `--model`: 모델 파일 경로. 스크립트 실행 시 반드시 제공해야 하는 필수 인수입니다. +- `-n`, `--n-token`: 추론 중 생성할 토큰 수. 기본값은 128인 선택적 인수입니다. +- `-p`, `--n-prompt`: 텍스트 생성을 위해 사용할 프롬프트 토큰 수. 기본값은 512인 선택적 인수입니다. +- `-t`, `--threads`: 추론 실행에 사용할 스레드 수. 기본값은 2인 선택적 인수입니다. +- `-h`, `--help`: 도움말 메시지를 표시하고 종료합니다. 사용 정보를 표시하려면 이 인수를 사용하십시오. + +예: + +```sh +python utils/e2e_benchmark.py -m /path/to/model -n 200 -p 256 -t 4 +``` + +이 명령은 `/path/to/model`에 있는 모델을 사용하여 추론 벤치마크를 실행하고, 256 토큰 프롬프트에서 200개의 토큰을 생성하며, 4개의 스레드를 활용합니다. + +공개 모델에서 지원하지 않는 모델 레이아웃의 경우, 지정된 모델 레이아웃으로 더미 모델을 생성하고 시스템에서 벤치마크를 실행하는 스크립트를 제공합니다. + +```bash +python utils/generate-dummy-bitnet-model.py models/bitnet_b1_58-large --outfile models/dummy-bitnet-125m.tl1.gguf --outtype tl1 --model-size 125M + +# 생성된 모델로 벤치마크 실행, -m을 사용하여 모델 경로 지정, -p를 사용하여 처리된 프롬프트 지정, -n을 사용하여 생성할 토큰 수 지정 +python utils/e2e_benchmark.py -m models/dummy-bitnet-125m.tl1.gguf -p 512 -n 128 +``` + +### `.safetensors` 체크포인트에서 변환 + +```sh +# .safetensors 모델 파일 준비 +huggingface-cli download microsoft/bitnet-b1.58-2B-4T-bf16 --local-dir ./models/bitnet-b1.58-2B-4T-bf16 + +# gguf 모델로 변환 +python ./utils/convert-helper-bitnet.py ./models/bitnet-b1.58-2B-4T-bf16 +``` + +### FAQ (자주 묻는 질문)📌 + +#### Q1: log.cpp의 std::chrono 관련 문제로 인해 llama.cpp 빌드 중 오류가 발생하며 빌드가 중단됩니다. + +**A:** +이는 최신 버전의 llama.cpp에서 발생한 문제입니다. 이 문제를 해결하려면 [토론](https://github.com/abetlen/llama-cpp-python/issues/1942)의 이 [커밋](https://github.com/tinglou/llama.cpp/commit/4e3db1e3d78cc1bcd22bcb3af54bd2a4628dd323)을 참조하십시오. + +#### Q2: Windows의 conda 환경에서 clang으로 빌드하려면 어떻게 해야 합니까? + +**A:** +프로젝트를 빌드하기 전에 다음을 실행하여 clang 설치 및 Visual Studio 도구에 대한 액세스를 확인하십시오. +``` +clang -v +``` + +이 명령은 올바른 버전의 clang을 사용하고 있는지 그리고 Visual Studio 도구를 사용할 수 있는지 확인합니다. 다음과 같은 오류 메시지가 표시되는 경우: +``` +'clang'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램 또는 배치 파일이 아닙니다. +``` + +이는 명령줄 창이 Visual Studio 도구에 대해 올바르게 초기화되지 않았음을 나타냅니다. + +• 명령 프롬프트를 사용하는 경우 다음을 실행하십시오. +``` +"C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat" -startdir=none -arch=x64 -host_arch=x64 +``` + +• Windows PowerShell을 사용하는 경우 다음 명령을 실행하십시오. +``` +Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" Enter-VsDevShell 3f0e31ad -SkipAutomaticLocation -DevCmdArguments "-arch=x64 -host_arch=x64" +``` + +이러한 단계를 수행하면 환경이 초기화되고 올바른 Visual Studio 도구를 사용할 수 있게 됩니다. diff --git a/SFT-Tuning.md b/SFT-Tuning.md new file mode 100644 index 00000000..6a706e59 --- /dev/null +++ b/SFT-Tuning.md @@ -0,0 +1,87 @@ +# 한국어 BitNet 언어 모델의 지도 학습 미세조정(SFT) 가이드 + +## 1. 지도 학습 미세조정(SFT) 소개 + +지도 학습 미세조정(Supervised Fine-Tuning, SFT)은 사전 학습된 대규모 언어 모델(LLM)을 특정 다운스트림 작업이나 원하는 행동에 맞게 조정하는 과정입니다. 이는 일반적으로 (입력, 원하는 출력) 쌍으로 구성된 레이블이 지정된 예제 데이터셋을 사용하여 모델을 추가로 학습시킴으로써 이루어집니다. SFT를 통해 모델은 특정 지시를 따르거나, 질문에 답하거나, 텍스트를 요약하는 등 다양한 작업을 더 잘 수행하도록 특화될 수 있습니다. + +## 2. BitNet 모델을 위한 SFT + +BitNet 모델, 특히 BitNet b1.58과 같은 변형은 가중치를 -1, 0, 1의 세 가지 값으로 제한하는 3진 가중치(ternary weights)를 사용하여 처음부터(from scratch) 사전 학습됩니다. 이러한 고유한 아키텍처는 SFT 과정에서 몇 가지 중요한 고려 사항을 제기합니다. + +### 사전 학습된 BitNet 모델에 SFT 적용 + +이미 BitNet b1.58 형식으로 사전 학습된 모델에 SFT를 적용하는 것을 목표로 합니다. + +#### 가중치 처리 방식 + +* **3진 가중치 유지:** SFT 과정에서 BitNet 모델의 핵심인 3진 가중치가 그대로 유지되는지가 중요한 질문입니다. BitNet의 주된 장점인 효율성(메모리, 속도)을 유지하려면 SFT 중에도 가중치가 -1, 0, 1로 계속 제한되어야 할 가능성이 높습니다. 만약 SFT 과정에서 가중치가 전체 정밀도로 변경된다면, BitNet의 핵심 이점이 사라질 수 있습니다. *주의: 이 부분에 대한 구체적인 공식 BitNet SFT 절차 문서는 현재 접근이 어려워, 이는 BitNet의 설계 목표에 기반한 추론입니다. 실제 적용 시에는 공식 문서를 반드시 확인해야 합니다.* +* **학습 중 가중치 업데이트:** 가중치가 3진으로 유지된다면, SFT 중 가중치 업데이트 메커니즘은 일반적인 부동소수점 업데이트와 다를 수 있습니다. 예를 들어, 업데이트된 가중치를 다시 -1, 0, 1 중 하나로 "반올림"하거나 투영하는 과정이 포함될 수 있습니다. + +#### 표준 SFT와의 잠재적 차이점 + +BitNet의 3진 가중치 아키텍처는 표준 SFT 절차와 비교하여 다음과 같은 부분에서 차이를 유발할 수 있습니다: + +* **옵티마이저(Optimizer) 선택:** 표준 AdamW 등이 여전히 사용될 수 있지만, 3진 가중치에 더 적합한 맞춤형 옵티마이저나 학습률 스케줄 조정이 필요할 수 있습니다. 예를 들어, 가중치의 이산적인 특성으로 인해 학습 과정이 불안정해지는 것을 방지하기 위한 기법이 필요할 수 있습니다. +* **학습률(Learning Rate) 스케줄:** 일반적인 SFT보다 더 작거나 특수한 형태의 학습률 스케줄이 필요할 수 있습니다. +* **정규화(Regularization):** 3진 가중치를 유지하는 데 도움이 되는 특별한 정규화 기법이 유용할 수 있습니다. + +#### `lm_head` 처리 + +사전 학습 시 전체 정밀도(예: FP16/BF16)로 유지되었던 언어 모델 헤드(`lm_head`)는 SFT 과정에서도 계속 전체 정밀도로 학습될 가능성이 높습니다. 이는 모델이 특정 작업에 대한 미묘한 출력 분포를 더 잘 학습하도록 돕습니다. + +## 3. 한국어 SFT 데이터셋 준비 + +효과적인 한국어 BitNet SFT를 위해서는 고품질의 한국어 지시-응답(instruction-following) 데이터셋이 필수적입니다. + +### 데이터셋 유형 및 품질 + +* **다양한 작업 포함:** 질의응답(Question-Answering), 요약(Summarization), 번역(Translation), 텍스트 생성(Text Generation), 분류(Classification), 대화(Dialogue) 등 다양한 유형의 작업을 포괄하는 데이터셋을 구성하는 것이 좋습니다. +* **지시-응답 쌍 (Prompt-Response Pairs):** 데이터는 일반적으로 사용자의 지시(프롬프트)와 모델이 생성해야 하는 바람직한 응답의 쌍으로 구성됩니다. 예: + * 프롬프트: "대한민국의 수도는 어디인가요?" + * 응답: "대한민국의 수도는 서울입니다." + * 프롬프트: "다음 문서를 세 문장으로 요약해 주세요: [긴 문서 내용]" + * 응답: "[요약된 세 문장]" +* **품질 관리:** 데이터의 정확성, 일관성, 다양성이 중요합니다. 모호하거나 잘못된 정보, 편향된 내용을 포함하는 데이터는 모델 성능에 부정적인 영향을 미칠 수 있습니다. 한국어의 자연스러움과 문법적 정확성도 중요합니다. + +### 데이터 소스 예시 + +* 공개된 한국어 QA 데이터셋 (예: KorQuAD 변형) +* 한국어 요약 데이터셋 +* 사용자가 직접 구축한 특정 작업 관련 지시-응답 데이터 +* 한국어 Alpaca, KoAlpaca와 같이 공개된 지시 데이터셋 + +## 4. 학습 과정 + +SFT의 일반적인 학습 목표는 모델이 주어진 프롬프트에 대해 원하는 응답을 정확하게 예측하도록 하는 것입니다. + +### 손실 함수 (Loss Function) + +일반적으로 응답(타겟 토큰)에 대한 표준 교차 엔트로피 손실(cross-entropy loss)이 사용됩니다. + +### 일반적인 SFT 학습 기법 + +* **데이터 패킹 (Data Packing):** 여러 개의 짧은 예제를 하나의 시퀀스로 묶어 학습 효율성을 높이는 기법입니다. 패딩(padding)을 줄여 GPU 활용도를 높일 수 있습니다. +* **입력/프롬프트 토큰 마스킹 (Masking of Input/Prompt Tokens):** 손실을 계산할 때, 프롬프트 부분의 토큰은 무시하고 실제 모델이 생성해야 하는 응답 부분의 토큰에 대해서만 손실을 계산합니다. 이는 모델이 프롬프트를 단순히 복사하는 것이 아니라 응답 생성에 집중하도록 유도합니다. +* **하이퍼파라미터 튜닝:** 배치 크기, 학습률, 에포크(epoch) 수 등의 하이퍼파라미터를 신중하게 조정해야 합니다. + +### BitNet 특화 고려 사항 + +앞서 언급했듯이, BitNet의 3진 가중치를 효과적으로 학습시키기 위한 특정 옵티마이저 설정이나 학습 안정화 기법이 필요할 수 있습니다. 이는 실험을 통해 최적화되거나 관련 연구에서 제안될 수 있습니다. + +## 5. 평가 + +SFT된 한국어 BitNet 모델의 성능은 수행하려는 특정 작업에 따라 평가됩니다. + +* **자동 평가 지표:** + * **질의응답:** Exact Match (EM), F1 Score + * **요약:** ROUGE, BLEU (요약문과 참조 요약문 간의 유사도) + * **번역:** BLEU, METEOR + * **분류:** 정확도(Accuracy), 정밀도(Precision), 재현율(Recall), F1 Score +* **인간 평가:** 특히 개방형 질문 답변, 창의적 텍스트 생성, 대화 능력 등과 같이 자동 평가가 어려운 작업의 경우, 인간 평가자가 모델 출력의 품질, 관련성, 유창성 등을 직접 평가하는 것이 중요합니다. +* **벤치마크 데이터셋:** 공개된 한국어 LLM 평가 벤치마크(예: KLUE, KoBEST 등)를 사용하여 다른 모델과 성능을 비교할 수 있습니다. + +## 6. 결론 + +한국어 BitNet 언어 모델의 SFT는 사전 학습된 모델의 효율성을 유지하면서 특정 작업에 대한 성능을 극대화하는 것을 목표로 합니다. 이 과정에서는 BitNet 고유의 3진 가중치 특성을 고려한 학습 전략과 고품질의 한국어 지시-응답 데이터셋이 핵심적인 역할을 합니다. + +본 문서는 일반적인 SFT 원칙과 BitNet 아키텍처의 특성을 결합하여 한국어 BitNet 모델의 SFT에 대한 개괄적인 지침을 제공합니다. 그러나 BitNet 모델을 위한 최적의 SFT 방법론과 구체적인 절차는 모델 개발자가 제공하는 공식 문서나 관련 연구 논문을 통해 확인하는 것이 가장 정확합니다. 특히 SFT 중 가중치 처리 방식과 같은 핵심적인 세부 사항은 공식적인 정보가 중요합니다. From 9225e6010803f33aab8a38ff1ae9ba70cb0d0dc4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:37:00 +0000 Subject: [PATCH 2/2] Here's my take on enhancing the Korean BitNet documentation with practical details. I've significantly updated the Korean BitNet documentation (`Pretrain-Tuning.md` and `SFT-Tuning.md`) based on your feedback and my analysis of the tinyllama-bitnet repository. Here are the key improvements I made: - **Clarified BitNet definition:** I emphasized BitNet as a comprehensive training and inference framework, not just a model architecture. - **Detailed `Pretrain-Tuning.md`:** - I added practical guidance on data preparation for Korean LLMs. - I included environment setup details, including library requirements and model configuration. - I provided an in-depth explanation of the BitLinear layer and its implementation (activation/weight quantization, STE). - I outlined step-by-step pretraining execution methods with hyperparameter details, referencing `tinyllama-bitnet`. - **Detailed `SFT-Tuning.md`:** - I included guidance on preparing Korean SFT datasets (instruction/dialogue). - I added SFT environment setup and model loading information. - I detailed SFT execution methods with specific hyperparameters. - I introduced Direct Preference Optimization (DPO). - **Added comprehensive reference sections** to both documents, including links to relevant papers, code repositories (tinyllama-bitnet, microsoft/unilm, microsoft/BitNet), and other resources. These enhancements should provide you with more practical, in-depth, and actionable information for pretraining or fine-tuning BitNet models for the Korean language. --- Pretrain-Tuning.md | 266 ++++++++++++++++++++++++++++++++++++++++----- SFT-Tuning.md | 215 +++++++++++++++++++++++++++++++----- 2 files changed, 424 insertions(+), 57 deletions(-) diff --git a/Pretrain-Tuning.md b/Pretrain-Tuning.md index 34f0ba60..2c2fd6f3 100644 --- a/Pretrain-Tuning.md +++ b/Pretrain-Tuning.md @@ -2,6 +2,8 @@ ## 서론 +BitNet을 이해하기 위해서는 단순히 특정 모델 아키텍처로만 한정짓기보다 더 넓은 프레임워크로 접근하는 것이 중요합니다. BitNet은 다음과 같은 핵심 요소들을 포함하는 종합적인 접근 방식을 의미합니다: (1) 가중치의 초저비트 양자화(예: 1비트 또는 1.58비트 3진 가중치) 및 활성화 값의 저비트 양자화(예: 8비트), (2) 처음부터 양자화를 고려하여 학습하는 양자화 인식 학습(Quantization-Aware Training, QAT) 방식 채택, (3) 전체 정밀도(FP16/BF16) 모델과 유사한 성능을 목표로 하면서 메모리 사용량, 추론 속도, 에너지 소비 측면에서 상당한 효율성 향상을 추구, (4) `BitLinear`와 같은 맞춤형 레이어 구성 요소 및 `bitnet.cpp`와 같은 최적화된 추론 엔진의 활용 가능성. 이러한 요소들이 결합되어 BitNet의 특징을 이룹니다. + BitNet은 최근 주목받고 있는 1비트 대규모 언어 모델(LLM) 아키텍처로, 기존 부동소수점(FP16/BF16) 모델에 비해 메모리 사용량, 에너지 소비, 추론 속도 면에서 상당한 이점을 제공하는 것을 목표로 합니다. 본 문서는 한국어 BitNet 언어 모델, 특히 BitNet b1.58 변형을 사전 학습하는 방법에 대한 핵심 개념과 일반적인 지침을 제공합니다. BitNet 모델, 특히 BitNet b1.58은 가중치를 -1, 0, 1의 세 가지 값으로 표현하는 3진 가중치(ternary weights)를 특징으로 합니다. 이러한 접근 방식은 모델의 크기를 크게 줄이고 계산 효율성을 향상시킵니다. @@ -28,55 +30,261 @@ BitNet b1.58의 핵심은 대부분의 가중치를 -1, 0, 또는 1로 제한하 BitNet 사전 학습의 궁극적인 목표는 전체 정밀도 모델과 비슷한 수준의 언어 이해 및 생성 능력을 달성하면서도, 추론 시 훨씬 낮은 지연 시간(latency), 더 적은 메모리 사용량, 그리고 감소된 에너지 소비를 실현하는 것입니다. -## 한국어 데이터 고려 사항 +## 데이터 준비 (Data Preparation) 한국어 BitNet 모델을 성공적으로 사전 학습하려면 방대하고 품질 좋은 한국어 텍스트 코퍼스가 필수적입니다. -### 1. 코퍼스 규모 및 품질 - -모델의 성능은 학습 데이터의 규모와 질에 크게 좌우됩니다. 다양한 주제와 스타일을 포괄하는 수십억 토큰 규모의 데이터셋을 목표로 해야 합니다. 데이터는 철자 오류, 문법적 오류, 불일치성 등을 최소화하기 위해 신중하게 정제되어야 합니다. - -### 2. 데이터 소스 +### 1. 한국어 데이터셋 유형 +일반적으로 사용될 수 있는 한국어 데이터셋 유형은 다음과 같습니다: * **뉴스 기사:** 시사적인 내용과 정제된 문장을 제공합니다. * **도서:** 다양한 어휘와 문체, 깊이 있는 내용을 포함합니다. -* **웹 텍스트:** 블로그, 포럼, 웹사이트 등에서 수집된 광범위한 주제의 텍스트입니다. 다만, 정제 과정이 중요합니다. +* **웹 텍스트:** 블로그, 포럼, 웹사이트 등에서 수집된 광범위한 주제의 텍스트입니다. 정제 과정이 중요합니다. * **학술 자료:** 전문 용어와 논리적인 글쓰기 스타일을 학습하는 데 도움이 됩니다. * **대화 데이터:** 채팅, 메신저 대화 등은 모델의 자연스러운 대화 능력을 향상시킬 수 있습니다. -데이터 수집 시 저작권 및 개인정보 보호 규정을 준수하는 것이 중요합니다. +데이터의 **품질과 규모**는 모델 성능에 결정적인 영향을 미칩니다. 다양한 주제와 스타일을 포괄하며, 철자 및 문법적 오류가 적고 일관성 있는 수십억 토큰 규모의 데이터셋을 목표로 해야 합니다. 데이터 수집 시 저작권 및 개인정보 보호 규정을 준수하는 것이 중요합니다. -## 학습 과정 개요 +### 2. 데이터 전처리 및 토큰화 (Data Preprocessing and Tokenization) -BitNet 모델의 구체적인 학습 레시피는 공식 BitNet 논문 및 관련 간행물에서 더 자세히 찾아볼 수 있지만, 일반적인 사전 학습 과정은 다음과 같은 요소들을 포함합니다. +사전 학습을 위해서는 텍스트 데이터를 모델이 이해할 수 있는 숫자 시퀀스로 변환하는 토큰화 과정이 필요합니다. `tinyllama-bitnet` 리포지토리의 `train.py` 스크립트를 예시로 설명합니다. -### 1. 토큰화 (Tokenization) +* **토크나이저 로딩**: + ```python + tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf") + ``` + 위 코드는 `meta-llama/Llama-2-7b-hf` 모델의 토크나이저를 사용합니다. 이 토크나이저는 주로 영어에 최적화되어 있지만, 다국어 처리 능력을 어느 정도 갖추고 있을 수 있습니다. -한국어의 특성(교착어, 띄어쓰기 등)을 잘 처리할 수 있는 토큰화 방식이 필요합니다. SentencePiece, BPE (Byte Pair Encoding) 또는 WordPiece와 같은 서브워드 토큰화 방법론을 기반으로 한국어에 맞게 학습된 토크나이저를 사용하는 것이 일반적입니다. 토크나이저의 어휘 크기는 모델 성능과 효율성에 영향을 미치므로 신중하게 결정해야 합니다. - -### 2. 학습 목표 (Training Objectives) +* **`tokenize` 함수 로직**: + `train.py`의 `tokenize` 함수는 다음과 같이 동작합니다: + 1. 여러 텍스트 문서를 하나로 결합합니다 (`concatenate_texts`). + 2. 각 텍스트의 끝에 문장 종료 토큰(`eos_token_id`)을 추가합니다. + 3. 결합된 텍스트를 모델의 `context_length` (예: 2048)에 맞춰 청크(chunk)로 나눕니다. 각 청크는 `input_ids`의 시퀀스가 됩니다. + + ```python + # train.py 내의 tokenize 함수 예시 (개념적) + def tokenize_function(examples): + # 텍스트들을 하나로 합치고 eos 토큰 추가 + concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()} + total_length = len(concatenated_examples[list(examples.keys())[0]]) + # context_length 단위로 청크 분할 + total_length = (total_length // context_length) * context_length + result = { + k: [t[i : i + context_length] for i in range(0, total_length, context_length)] + for k, t in concatenated_examples.items() + } + result["labels"] = result["input_ids"].copy() # CLM의 경우 labels는 input_ids와 동일 + return result + ``` + +* **사전 토큰화된 데이터셋 활용**: + `train.py`에서는 `xz56/openwebtext-tokenized-small`와 같이 이미 토큰화된 데이터셋을 사용하는 옵션도 제공합니다. 이는 대규모 데이터셋의 경우 토큰화 시간을 절약할 수 있는 방법입니다. + +* **한국어 토큰화 고려 사항**: + * `tinyllama-bitnet` 예제는 Llama-2 토크나이저를 사용하지만, 한국어 모델의 성능을 최적화하기 위해서는 한국어의 특성(교착어, 띄어쓰기 등)을 잘 처리할 수 있는 한국어 전용 토크나이저를 사용하거나 직접 학습시키는 것이 이상적입니다. (예: SentencePiece BPE 토크나이저) + * 한국어 전용 토크나이저를 사용할 경우, 어휘 크기(vocab size) 결정도 중요한 요소입니다. + +### 3. 데이터 형식/구조 (Data Format/Structure) + +* **입력 데이터**: 일반적으로 `.txt` 파일이나 `.jsonl` 파일 형태로 구성된 일반 텍스트(plain text)입니다. +* **토큰화 이후**: 텍스트는 `input_ids` (정수 시퀀스)로 변환됩니다. Hugging Face `datasets` 라이브러리는 이러한 데이터를 효율적으로 로드하고 처리하며, 메모리 매핑(memory mapping)과 같은 기술을 사용하여 대용량 데이터셋도 다룰 수 있게 합니다. 각 샘플은 보통 다음과 같은 필드를 가질 수 있습니다: + * `input_ids`: 토큰 ID의 리스트 + * `attention_mask`: 어텐션 메커니즘에서 어떤 토큰에 주목해야 하는지를 나타내는 마스크 (일반적으로 CLM에서는 모든 토큰에 주목) + * `labels`: CLM의 경우 `input_ids`와 동일하며, 모델이 예측해야 하는 타겟 토큰 ID + +## 학습 환경 설정 (Training Environment Setup) + +BitNet 모델을 사전 학습하기 위한 환경 설정 과정을 `tinyllama-bitnet` 예제를 중심으로 설명합니다. + +### 1. 주요 라이브러리 + +`train.py` 스크립트 실행에 필요한 주요 Python 라이브러리는 다음과 같습니다: +* `transformers`: Hugging Face의 트랜스포머 모델 및 유틸리티 사용 +* `datasets`: 데이터셋 로딩 및 전처리 +* `torch`: PyTorch 딥러닝 프레임워크 +* `wandb` (선택 사항): 실험 추적 및 시각화를 위한 Weights & Biases +* `huggingface_hub` (선택 사항): 모델 및 토크나이저를 허깅페이스 허브에 업로드/다운로드 + +### 2. 모델 구성 (`Tiny Llama` 예시) + +`train.py`에서는 `meta-llama/Llama-2-7b-hf`의 설정을 기반으로 작은 모델(`Tiny Llama` 스타일)을 구성합니다. + +```python +# AutoConfig를 사용하여 Llama-2 7B 모델 설정을 로드 +config = AutoConfig.from_pretrained("meta-llama/Llama-2-7b-hf") + +# 모델 크기 축소를 위한 설정 변경 예시 +config.hidden_size = 1024 # 'dim' +config.num_attention_heads = 8 # 'n_heads' +config.num_hidden_layers = 8 # 'n_layers' +config.intermediate_size = 2048 + +# 새로운 모델을 AutoModelForCausalLM.from_config(config)로 생성 가능 +# model = AutoModelForCausalLM.from_config(config) +``` +위와 같이 `hidden_size` (차원), `num_attention_heads` (어텐션 헤드 수), `num_hidden_layers` (레이어 수), `intermediate_size` (MLP 중간 크기) 등을 조정하여 모델의 크기를 결정합니다. + +### 3. BitNet 아키텍처로 변환 + +표준 트랜스포머 모델을 BitNet 아키텍처로 변환하는 과정은 `tinyllama-bitnet`의 `utils.py`에 정의된 `convert_to_bitnet` 함수를 통해 이루어집니다. `train.py`에서 이 함수를 호출합니다. + +```python +# model = AutoModelForCausalLM.from_config(config) # 예시 모델 생성 후 +# model = convert_to_bitnet(model, copy_weights=False) # BitNet으로 변환 +``` + +`convert_to_bitnet(model, copy_weights=False)` 함수의 주요 단계는 다음과 같습니다: + +1. **`nn.Linear`를 `BitLinear`로 교체**: + * 모델 내의 `LlamaSdpaAttention` 레이어와 `LlamaMLP` 레이어에 포함된 모든 `nn.Linear` 계층을 사용자 정의 `BitLinear` 계층으로 대체합니다. `BitLinear`는 BitNet의 핵심 구성 요소로, 가중치와 활성화 값의 양자화를 처리합니다. +2. **`input_layernorm` 제거**: + * `LlamaDecoderLayer` 내의 `input_layernorm` (일반적으로 `LlamaRMSNorm`)을 제거하고, 이를 `nn.Identity()` (아무 연산도 하지 않는 항등 함수)로 대체합니다. 이는 BitNet 아키텍처의 특징 중 하나로, `BitLinear` 내부에서 정규화를 처리하기 때문일 수 있습니다. + +`copy_weights=False` 인자는 모델을 처음부터 학습시킴을 의미합니다. 만약 사전 학습된 가중치를 BitNet으로 변환하는 경우라면 `True`로 설정하고 가중치 복사 로직이 추가로 필요할 수 있으나, BitNet은 일반적으로 처음부터 학습합니다. + +## `BitLinear` 계층 설명 (BitLinear Layer Explanation) + +`BitLinear`는 `tinyllama-bitnet/utils.py`에 정의된 사용자 정의 `nn.Linear` 계층으로, BitNet의 핵심적인 연산을 수행합니다. + +```python +# class BitLinear(nn.Linear): # utils.py 내의 BitLinear 정의 (개념적) +# def __init__(self, *args, **kwargs): +# super().__init__(*args, **kwargs) +# self.norm = LlamaRMSNorm(self.in_features, eps=1e-6) # 내부 RMSNorm +# +# def forward(self, x): +# # 입력 정규화 +# x_norm = self.norm(x) +# +# # 활성화 양자화 (Activation Quantization) - Per-token 8-bit +# # STE (Straight-Through Estimator)를 사용하여 역전파 시 기울기 흐름 유지 +# x_quant = x_norm + (activation_quant(x_norm) - x_norm).detach() +# +# # 가중치 양자화 (Weight Quantization) - Per-tensor 1.58-bit (ternary) +# # STE 사용 +# w_quant = self.weight + (weight_quant(self.weight) - self.weight).detach() +# +# # 양자화된 활성화와 가중치를 사용하여 선형 변환 +# # F.linear는 y = xW^T + b 연산을 수행 +# y = F.linear(x_quant, w_quant, self.bias) +# +# return y +``` +`BitLinear`의 `forward` 연산 과정은 다음과 같습니다: + +1. **내부 `LlamaRMSNorm` 적용**: 입력 `x`에 대해 먼저 `LlamaRMSNorm`을 적용하여 정규화합니다 (`x_norm`). +2. **활성화 양자화 (`activation_quant`)**: 정규화된 활성화 값 `x_norm`을 토큰별(per-token)로 8비트 양자화합니다. 이 과정에서 Straight-Through Estimator (STE)가 사용됩니다: `x_quant = x_norm + (activation_quant(x_norm) - x_norm).detach()`. 순전파 시에는 양자화된 값을 사용하지만, 역전파 시에는 `detach()`를 통해 양자화 연산의 기울기를 무시하고 `x_norm`의 기울기를 그대로 전달하여 학습을 가능하게 합니다. +3. **가중치 양자화 (`weight_quant`)**: 계층의 가중치 `self.weight`를 텐서별(per-tensor)로 1.58비트 3진(-1, 0, 1) 양자화합니다. 여기서도 STE가 사용됩니다: `w_quant = self.weight + (weight_quant(self.weight) - self.weight).detach()`. +4. **선형 변환**: 양자화된 활성화 `x_quant`와 양자화된 가중치 `w_quant`를 사용하여 `F.linear` 연산을 수행합니다. + +`utils.py`의 주석에 따르면, "**This is only for training, and kernel optimization is needed for efficiency.**" 즉, 이 `BitLinear` 구현은 학습을 위한 것이며, 실제 추론 시 효율성을 극대화하기 위해서는 최적화된 커널(예: `bitnet.cpp`에서 제공하는 커널)이 필요합니다. + +## 학습 실행 방법 (Training Execution Method) + +### 1. 양자화 인식 학습 (Quantization-Aware Training, QAT) + +BitNet의 핵심 학습 방식은 QAT입니다. 이는 모델 학습 과정에서 양자화(가중치 및 활성화의 저비트 표현)를 시뮬레이션하여, 모델이 양자화로 인한 성능 저하에 강인해지도록 만듭니다. `BitLinear` 계층 내의 양자화 로직과 STE 사용이 QAT를 가능하게 합니다. + +### 2. 데이터 콜레이터 (Data Collator) + +인과적 언어 모델링(Causal Language Modeling, CLM)을 위해 `DataCollatorForLanguageModeling`을 사용합니다. +```python +data_collator = DataCollatorForLanguageModeling(tokenizer, mlm=False) +# mlm=False는 CLM을 의미 (Masked Language Modeling이 아님) +``` + +### 3. `TrainingArguments` 설정 + +Hugging Face `Trainer`를 사용하기 위한 학습 관련 인자들을 설정합니다. `train.py`의 예시는 다음과 같습니다: + +```python +args = TrainingArguments( + output_dir="output_tinyllama", + per_device_train_batch_size=8, # 장치당 배치 크기 + gradient_accumulation_steps=16, # 그래디언트 축적 스텝 + num_train_epochs=1, # 총 학습 에포크 + weight_decay=0.1, # 가중치 감쇠 + warmup_steps=750, # 웜업 스텝 수 (또는 warmup_ratio=0.1) + lr_scheduler_type="cosine", # 학습률 스케줄러 유형 (예: cosine, polynomial) + learning_rate=1.5e-3, # 학습률 + save_steps=5000, + logging_steps=10, + fp16=True, # 혼합 정밀도 학습 활성화 + # ... 기타 인자들 +) +``` + +* **유효 배치 크기 (Effective Batch Size)**: `per_device_train_batch_size * gradient_accumulation_steps * num_gpus`. + `train.py` 예시에서는 `8 * 16 = 128` 입니다. +* **배치당 토큰 수**: "배치당 토큰 수는 최소 ~100k (10만)"를 권장합니다. 이는 `유효 배치 크기 * context_length`로 계산할 수 있습니다. 예를 들어 유효 배치 크기가 128이고 `context_length`가 2048이라면, 배치당 토큰 수는 `128 * 2048 = 262,144` (약 262k)입니다. + +### 4. 하이퍼파라미터 (Hyperparameters) + +사용자 피드백 및 일반적인 BitNet 학습 경험에 기반한 하이퍼파라미터 권장 사항은 다음과 같습니다 (`train.py`의 값과 다를 수 있음): + +* **옵티마이저 (Optimizer)**: AdamW (PyTorch 기본값 사용 가능). BitNet 관련 연구에서는 Adam의 β₁=0.9, β₂=0.98을 사용하는 경우가 많습니다. `train.py`는 `transformers`의 기본 AdamW 설정을 따릅니다. +* **학습률 스케줄 (Learning Rate Schedule)**: Polynomial decay 또는 Cosine decay (`lr_scheduler_type`으로 설정). `train.py`는 `cosine`을 사용합니다. +* **웜업 (Warmup)**: 전체 학습 스텝의 일정 비율(예: `warmup_ratio=0.1` in `train.py`) 또는 고정된 스텝 수(예: 750 스텝). +* **배치 크기 (Batch Size)**: 가능한 큰 배치당 토큰 수를 사용하는 것이 좋습니다 (예: 256K 토큰 이상). 이는 `per_device_train_batch_size`, `gradient_accumulation_steps`, `context_length`를 조정하여 달성합니다. +* **드롭아웃 (Dropout)**: 일반적으로 사용하지 않습니다 (`dropout=0`). +* **가중치 감쇠 (Weight Decay)**: 모델 크기에 따라 0.01 또는 0.05 (매우 큰 모델의 경우) 등을 사용합니다. `train.py`는 0.1을 사용합니다. +* **학습률 (Learning Rate)**: 모델 크기에 따라 다릅니다. + * `tinyllama-bitnet` (~84M 모델): `1.5e-3` + * 125M 모델: 약 `2.4e-3` + * 13B-30B 모델: 약 `4e-4` + * BitNet b1.58-2B-4T 모델의 경우, 2단계 학습률 스케줄(더 높은 LR로 시작하여 중간에 낮추는 방식)을 사용했다는 고급 정보도 있습니다. + +### 5. 혼합 정밀도 학습 (Mixed-Precision Training) + +`TrainingArguments`에서 `fp16=True` (또는 `bf16=True` 사용 가능 시)를 설정하여 혼합 정밀도 학습을 활성화합니다. 이는 학습 속도를 높이고 메모리 사용량을 줄여줍니다. +사용자 피드백에 따르면, 옵티마이저 상태(optimizer states)와 그래디언트(gradients)는 종종 BF16 또는 FP32와 같은 더 높은 정밀도로 유지되어 학습 안정성을 돕습니다. `transformers.Trainer`는 이를 자동으로 처리할 수 있습니다. + +### 6. 분산 학습 (Distributed Training) + +`tinyllama-bitnet` 예제는 단일 GPU 학습에 초점을 맞추고 있지만, 더 큰 모델(수십억 파라미터 이상)을 사전 학습하려면 분산 학습 환경이 필수적입니다. DeepSpeed (ZeRO 최적화 포함), PyTorch FSDP, Megatron-LM 등의 프레임워크를 사용하여 여러 GPU 또는 여러 노드에 걸쳐 학습을 확장할 수 있습니다. + +### 7. `Trainer` 실행 및 모델 저장 + +학습을 시작하고 완료 후 모델을 저장합니다. +```python +# Trainer 초기화 +trainer = Trainer( + model=model, + tokenizer=tokenizer, + args=args, + train_dataset=tokenized_datasets["train"], # 학습 데이터셋 + eval_dataset=tokenized_datasets["validation"], # 평가 데이터셋 (선택 사항) + data_collator=data_collator, +) + +# 학습 실행 +trainer.train() + +# 모델 저장 +trainer.save_model() # output_dir에 저장됨 +# tokenizer.save_pretrained(args.output_dir) # 토크나이저도 함께 저장 +``` + +## 학습 목표 (Training Objectives) 표준적인 대규모 언어 모델의 학습 목표가 BitNet 사전 학습에도 적용될 수 있습니다: -* **인과적 언어 모델링 (Causal Language Modeling, CLM):** 다음 토큰을 예측하는 방식입니다. GPT 계열 모델에서 주로 사용됩니다. +* **인과적 언어 모델링 (Causal Language Modeling, CLM):** 다음 토큰을 예측하는 방식입니다. GPT 계열 모델에서 주로 사용되며, `tinyllama-bitnet` 예제에서도 이 방식을 사용합니다. * **마스크 언어 모델링 (Masked Language Modeling, MLM):** 입력 텍스트의 일부 토큰을 마스킹하고, 모델이 이를 예측하도록 학습합니다. BERT 계열 모델에서 사용됩니다. -BitNet의 경우, 특정 학습 목표나 변형이 제안될 수 있으므로 관련 연구를 참고하는 것이 좋습니다. - -### 3. 모델 아키텍처 - -트랜스포머(Transformer) 아키텍처를 기반으로 하되, BitNet의 3진 가중치를 적용하기 위한 수정된 레이어 구현이 필요합니다. 여기에는 사용자 정의 커널이나 연산 최적화가 포함될 수 있습니다. +BitNet의 경우, 특정 학습 목표나 변형이 제안될 수 있으므로 관련 연구를 참고하는 것이 좋습니다. (이 섹션은 기존 내용을 바탕으로 재구성) -### 4. 최적화 및 하이퍼파라미터 - -AdamW와 같은 표준적인 옵티마이저가 사용될 수 있지만, 학습률(learning rate), 배치 크기(batch size), 학습 스케줄(learning rate schedule) 등은 BitNet의 특성과 사용되는 데이터셋에 맞게 조정되어야 합니다. 저정밀도 가중치 학습을 위한 특별한 정규화(regularization) 기법이나 학습 안정화 전략이 필요할 수도 있습니다. - -### 5. 계산 리소스 (Computational Resources) - -대규모 언어 모델의 사전 학습은 상당한 계산 리소스(GPU 또는 TPU)를 필요로 합니다. BitNet은 추론 시 효율성을 목표로 하지만, 사전 학습 과정 자체는 여전히 많은 연산 능력과 시간을 소모할 수 있습니다. 분산 학습(distributed training) 환경 구축이 일반적입니다. - -## 결론 +## 결론 (기존 내용 유지 또는 약간 수정) 한국어 BitNet 언어 모델의 사전 학습은 기존 LLM과는 다른 독특한 고려 사항, 특히 "처음부터 학습" 원칙과 3진 가중치 시스템을 중심으로 이루어집니다. 고품질의 대규모 한국어 코퍼스, 적절한 토큰화, 그리고 BitNet 아키텍처에 맞는 학습 전략을 통해 효율적이면서도 강력한 한국어 1비트 LLM을 개발할 수 있을 것입니다. 본 문서는 개괄적인 지침을 제공하며, 실제 구현 및 최적의 성능을 위해서는 공식 BitNet 간행물에서 제공하는 구체적인 학습 방법론과 실험 결과를 참조하는 것이 중요합니다. + +## 참고 자료 (References) + +* **tinyllama-bitnet GitHub Repository:** [pranavjad/tinyllama-bitnet](https://github.com/pranavjad/tinyllama-bitnet) - 본 문서에서 많은 코드 예시와 학습 절차 아이디어를 참조한 저장소입니다. +* **The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits (BitNet b1.58):** [arXiv:2402.17764](https://arxiv.org/abs/2402.17764) - 1.58비트 BitNet에 대한 핵심 논문입니다. +* **BitNet: Scaling 1-bit Transformers for Large Language Models (Original BitNet):** [arXiv:2310.11453](https://arxiv.org/abs/2310.11453) - 초기 1비트 BitNet 아키텍처에 대한 논문입니다. +* **The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ.pdf:** [Microsoft UniLM GitHub](https://github.com/microsoft/unilm/blob/master/bitnet/The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ.pdf) - Microsoft에서 제공하는 BitNet 학습 팁 및 FAQ 문서입니다. +* **microsoft/BitNet (bitnet.cpp):** [GitHub](https://github.com/microsoft/BitNet) - BitNet 모델을 위한 공식 C++ 추론 프레임워크 저장소입니다. +* **Hugging Face TRL (Transformer Reinforcement Learning):** [GitHub](https://github.com/huggingface/trl) - DPO(Direct Preference Optimization)와 같은 선호도 튜닝 기법을 구현하는 데 유용한 라이브러리입니다. (SFT-Tuning.md에 특히 관련) diff --git a/SFT-Tuning.md b/SFT-Tuning.md index 6a706e59..6228f477 100644 --- a/SFT-Tuning.md +++ b/SFT-Tuning.md @@ -2,6 +2,8 @@ ## 1. 지도 학습 미세조정(SFT) 소개 +BitNet은 특정 모델 아키텍처를 넘어, 가중치 및 활성화 값의 저비트 양자화(예: 1.58비트 3진 가중치, 8비트 활성화), 처음부터 양자화를 고려한 학습(QAT), 그리고 `BitLinear` 계층 및 `bitnet.cpp`와 같은 최적화된 구성 요소를 포함하는 포괄적인 프레임워크입니다. 이는 전체 정밀도 모델 성능에 근접하면서 메모리, 속도, 에너지 효율성을 극대화하는 것을 목표로 합니다. + 지도 학습 미세조정(Supervised Fine-Tuning, SFT)은 사전 학습된 대규모 언어 모델(LLM)을 특정 다운스트림 작업이나 원하는 행동에 맞게 조정하는 과정입니다. 이는 일반적으로 (입력, 원하는 출력) 쌍으로 구성된 레이블이 지정된 예제 데이터셋을 사용하여 모델을 추가로 학습시킴으로써 이루어집니다. SFT를 통해 모델은 특정 지시를 따르거나, 질문에 답하거나, 텍스트를 요약하는 등 다양한 작업을 더 잘 수행하도록 특화될 수 있습니다. ## 2. BitNet 모델을 위한 SFT @@ -29,47 +31,195 @@ BitNet의 3진 가중치 아키텍처는 표준 SFT 절차와 비교하여 다 사전 학습 시 전체 정밀도(예: FP16/BF16)로 유지되었던 언어 모델 헤드(`lm_head`)는 SFT 과정에서도 계속 전체 정밀도로 학습될 가능성이 높습니다. 이는 모델이 특정 작업에 대한 미묘한 출력 분포를 더 잘 학습하도록 돕습니다. -## 3. 한국어 SFT 데이터셋 준비 +## 3. SFT 데이터 준비 (SFT Data Preparation) + +효과적인 한국어 BitNet SFT를 위해서는 고품질의 한국어 지시(instruction) 및 응답 데이터셋이 필수적입니다. + +### 3.1. 한국어 SFT 데이터셋 유형 + +* **지시-응답 데이터셋 (Instruction-Following Datasets):** 특정 작업을 수행하도록 지시하는 프롬프트와 그에 대한 적절한 응답으로 구성됩니다. + * 예: 질의응답, 요약, 번역, 코드 생성, 정보 추출, 창의적 글쓰기 등. +* **대화 데이터셋 (Dialogue Datasets):** 사용자-모델 간의 여러 턴(turn)으로 이루어진 대화 형식의 데이터입니다. 모델이 이전 대화 내용을 기억하고 문맥에 맞는 응답을 생성하도록 학습합니다. + +### 3.2. 한국어 SFT 데이터 소스 예시 + +* **AI Hub 데이터셋:** NIA AI Hub ([aihub.or.kr](https://aihub.or.kr))에서 제공하는 다양한 한국어 말뭉치 및 대화형 데이터셋을 활용할 수 있습니다. (예: 한국어 대화 요약, 한국어 문서요약, 질의응답 등) +* **로컬 구축 데이터셋:** + * **KoAlpaca:** 스탠포드 대학의 Alpaca 프로젝트 결과를 한국어로 번역하고 개선한 데이터셋. + * 기타 연구자들이나 기관에서 공개한 한국어 지시-응답 데이터셋. +* **자체 제작 데이터셋:** 특정 도메인이나 작업에 특화된 SFT 데이터셋을 직접 구축할 수 있습니다. 이 경우 데이터의 품질 관리가 매우 중요합니다. + +### 3.3. 데이터 형식 및 구조 + +SFT 데이터셋은 주로 JSONL (JSON Lines) 형식으로 구성되며, 각 줄이 하나의 JSON 객체를 나타냅니다. -효과적인 한국어 BitNet SFT를 위해서는 고품질의 한국어 지시-응답(instruction-following) 데이터셋이 필수적입니다. +* **일반적인 지시-응답 형식:** + ```json + {"prompt": "질문: 한국의 수도는 어디인가요?", "response": "답변: 한국의 수도는 서울입니다."} + {"prompt": "다음 영단어의 뜻을 한국어로 알려주세요: 'efficiency'", "response": "'efficiency'는 한국어로 '효율성'을 의미합니다."} + ``` +* **대화 형식 예시 (간단화):** + ```json + {"id": "dialogue_1", "turns": ["사용자: 오늘 날씨 어때?", "모델: 오늘은 서울 기준으로 맑고 화창한 날씨가 예상됩니다."]} + ``` + 실제 대화 데이터셋은 더 복잡한 구조를 가질 수 있으며, 각 턴마다 발화자(speaker) 정보 등을 포함할 수 있습니다. -### 데이터셋 유형 및 품질 +* **데이터 품질의 중요성:** + * **명확한 지시:** 프롬프트는 모델이 수행해야 할 작업을 명확하게 지시해야 합니다. + * **고품질 응답:** 응답은 정확하고, 유용하며, 문법적으로 올바르고, 자연스러워야 합니다. + * **다양성:** 다양한 유형의 지시와 주제를 포함하여 모델의 일반화 성능을 높이는 것이 중요합니다. -* **다양한 작업 포함:** 질의응답(Question-Answering), 요약(Summarization), 번역(Translation), 텍스트 생성(Text Generation), 분류(Classification), 대화(Dialogue) 등 다양한 유형의 작업을 포괄하는 데이터셋을 구성하는 것이 좋습니다. -* **지시-응답 쌍 (Prompt-Response Pairs):** 데이터는 일반적으로 사용자의 지시(프롬프트)와 모델이 생성해야 하는 바람직한 응답의 쌍으로 구성됩니다. 예: - * 프롬프트: "대한민국의 수도는 어디인가요?" - * 응답: "대한민국의 수도는 서울입니다." - * 프롬프트: "다음 문서를 세 문장으로 요약해 주세요: [긴 문서 내용]" - * 응답: "[요약된 세 문장]" -* **품질 관리:** 데이터의 정확성, 일관성, 다양성이 중요합니다. 모호하거나 잘못된 정보, 편향된 내용을 포함하는 데이터는 모델 성능에 부정적인 영향을 미칠 수 있습니다. 한국어의 자연스러움과 문법적 정확성도 중요합니다. +* **프롬프트 템플릿 활용:** + 일관성 있는 학습을 위해 프롬프트 템플릿을 사용하는 것이 일반적입니다. 예를 들어, 모든 지시 앞에 특정 시스템 메시지나 역할을 부여하는 헤더를 추가할 수 있습니다. + ``` + ### Instruction: + {user_query} -### 데이터 소스 예시 + ### Response: + ``` -* 공개된 한국어 QA 데이터셋 (예: KorQuAD 변형) -* 한국어 요약 데이터셋 -* 사용자가 직접 구축한 특정 작업 관련 지시-응답 데이터 -* 한국어 Alpaca, KoAlpaca와 같이 공개된 지시 데이터셋 +### 3.4. SFT를 위한 데이터 전처리 -## 4. 학습 과정 +1. **토큰화 (Tokenization):** + * 사전 학습 단계에서 사용한 것과 **동일한 토크나이저**를 사용해야 합니다. + * 프롬프트와 응답을 각각 토큰화한 후, 일반적으로 하나의 시퀀스로 결합합니다. 특수 토큰(예: ``, ``, `[INST]`, `[/INST]`)을 사용하여 프롬프트와 응답, 또는 사용자 턴과 모델 턴을 구분할 수 있습니다. + * 예시적인 결합 방식: `[INST] {prompt} [/INST] {response}` 또는 `사용자: {prompt} 모델: {response}`. 이 형식은 사용하는 모델 아키텍처나 기존 학습 방식에 따라 달라질 수 있습니다. -SFT의 일반적인 학습 목표는 모델이 주어진 프롬프트에 대해 원하는 응답을 정확하게 예측하도록 하는 것입니다. +2. **마스킹 (Masking):** + * SFT의 핵심 목표는 모델이 주어진 프롬프트(또는 대화의 이전 부분)에 대해 적절한 **응답**을 생성하도록 학습하는 것입니다. + * 따라서 손실 함수(loss function)를 계산할 때, 프롬프트에 해당하는 토큰들은 무시(마스킹)하고, **응답에 해당하는 토큰들에 대해서만 손실을 계산**하는 것이 일반적입니다. 이렇게 하면 모델이 프롬프트를 단순히 반복하는 것을 방지하고 응답 생성 능력에 집중하게 됩니다. + * 데이터 콜레이터(Data Collator)에서 `labels`를 생성할 때, 프롬프트 부분의 토큰 ID를 특정 값(예: -100)으로 설정하여 손실 계산에서 제외합니다. -### 손실 함수 (Loss Function) +## 4. SFT 학습 환경 설정 (SFT Training Environment Setup) -일반적으로 응답(타겟 토큰)에 대한 표준 교차 엔트로피 손실(cross-entropy loss)이 사용됩니다. +SFT를 위한 학습 환경은 사전 학습 환경과 유사한 점이 많지만, 모델 로딩 및 데이터 처리 방식에서 차이가 있습니다. -### 일반적인 SFT 학습 기법 +### 4.1. 주요 라이브러리 -* **데이터 패킹 (Data Packing):** 여러 개의 짧은 예제를 하나의 시퀀스로 묶어 학습 효율성을 높이는 기법입니다. 패딩(padding)을 줄여 GPU 활용도를 높일 수 있습니다. -* **입력/프롬프트 토큰 마스킹 (Masking of Input/Prompt Tokens):** 손실을 계산할 때, 프롬프트 부분의 토큰은 무시하고 실제 모델이 생성해야 하는 응답 부분의 토큰에 대해서만 손실을 계산합니다. 이는 모델이 프롬프트를 단순히 복사하는 것이 아니라 응답 생성에 집중하도록 유도합니다. -* **하이퍼파라미터 튜닝:** 배치 크기, 학습률, 에포크(epoch) 수 등의 하이퍼파라미터를 신중하게 조정해야 합니다. +사전 학습과 마찬가지로 다음과 같은 라이브러리가 주로 사용됩니다: +* `transformers` +* `datasets` +* `torch` +* `wandb` (선택 사항) +* `huggingface_hub` (선택 사항) -### BitNet 특화 고려 사항 +### 4.2. 사전 학습된 BitNet 모델 로딩 -앞서 언급했듯이, BitNet의 3진 가중치를 효과적으로 학습시키기 위한 특정 옵티마이저 설정이나 학습 안정화 기법이 필요할 수 있습니다. 이는 실험을 통해 최적화되거나 관련 연구에서 제안될 수 있습니다. +SFT는 이미 사전 학습된 BitNet 모델에서 시작합니다. `tinyllama-bitnet`과 같은 프로젝트에서 사전 학습 후 저장된 모델 체크포인트를 로드합니다. -## 5. 평가 +```python +from transformers import AutoModelForCausalLM, AutoTokenizer +model_path = "path/to/your/pretrained_bitnet_model_checkpoint" # 사전 학습된 BitNet 모델 경로 +# 모델 로딩 시, BitLinear와 같은 사용자 정의 레이어가 등록되어 있어야 할 수 있음 +# 또는, 모델 저장/로드 방식이 BitNet 아키텍처를 올바르게 유지하는지 확인 필요 +model = AutoModelForCausalLM.from_pretrained(model_path) +tokenizer = AutoTokenizer.from_pretrained(model_path) # 사전 학습 시 사용한 토크나이저 로드 + +# 만약 로드된 모델이 BitNet 구성이 아니라면, +# convert_to_bitnet(model, copy_weights=True)와 유사한 함수로 변환해야 할 수 있으나, +# 일반적으로는 저장 시점의 BitNet 아키텍처 그대로 로드됩니다. +``` +사전 학습된 모델이 `BitLinear`와 같은 사용자 정의 모듈을 포함하고 있다면, 해당 모듈이 현재 환경에 정의되어 있어야 `AutoModelForCausalLM.from_pretrained`가 올바르게 작동합니다. + +### 4.3. SFT 스크립트 구조 (개념적) + +SFT 학습 스크립트는 사전 학습 스크립트(`tinyllama-bitnet/train.py` 등)의 구조를 기반으로 수정될 수 있습니다: + +* **데이터 로딩 및 전처리**: + * `datasets` 라이브러리를 사용하여 SFT용 JSONL 파일을 로드합니다. + * 위에서 설명한 토큰화 및 마스킹 전략을 적용하여 프롬프트-응답 쌍을 처리합니다. +* **모델**: 사전 학습된 BitNet 모델을 로드합니다. +* **토크나이저**: 사전 학습 시 사용된 것과 동일한 토크나이저를 사용합니다. +* **데이터 콜레이터**: `DataCollatorForLanguageModeling`을 계속 사용할 수 있지만, `labels` 필드에 프롬프트 마스킹이 올바르게 적용되도록 데이터 전처리 단계에서 처리해야 합니다. + +## 5. SFT 학습 실행 방법 (SFT Training Execution Method) + +### 5.1. 사전 학습된 BitNet 모델 로딩 + +학습 시작점에 특정 BitNet 모델 체크포인트를 명시적으로 로드하는 것이 중요합니다. + +### 5.2. 주요 SFT 하이퍼파라미터 + +SFT는 사전 학습과 비교하여 일반적으로 다른 하이퍼파라미터 값을 사용합니다: + +* **학습률 (Learning Rate)**: 사전 학습보다 훨씬 작은 학습률을 사용합니다. + * 일반적인 범위: `1e-5` ~ `5e-5` (예: `2e-5`). +* **에포크 (Epochs)**: 전체 데이터셋을 반복하는 횟수로, 사전 학습보다 훨씬 적습니다. + * 일반적인 범위: 1 ~ 5 에포크. 데이터셋 크기와 품질에 따라 조절합니다. +* **배치 크기 (Batch Size)**: GPU 메모리 및 시퀀스 길이에 따라 결정됩니다. SFT 데이터는 프롬프트와 응답을 포함하여 시퀀스 길이가 사전 학습보다 길어질 수 있으므로, 배치 크기를 줄여야 할 수 있습니다. +* **옵티마이저 (Optimizer)**: AdamW가 여전히 일반적으로 사용됩니다. (예: β₁=0.9, β₂=0.98 또는 PyTorch 기본값) +* **웜업 및 학습률 스케줄러 (Warmup & LR Scheduler)**: 사전 학습과 유사하게 짧은 기간의 웜업 후 코사인(cosine) 또는 선형(linear) 감쇠 스케줄러를 사용할 수 있습니다. +* **가중치 감쇠 (Weight Decay)**: 과적합을 방지하기 위해 작은 값 (예: 0.01)을 사용할 수 있습니다. + +### 5.3. 학습 루프 / `Trainer` API + +Hugging Face `Trainer` API는 SFT 과정에서도 동일하게 활용될 수 있습니다. 핵심적인 차이는 입력 데이터셋의 구성(지시-응답 쌍, 프롬프트 마스킹)과 하이퍼파라미터 설정에 있습니다. + +```python +from transformers import TrainingArguments, Trainer + +training_args = TrainingArguments( + output_dir="./sft_output_bitnet_korean", + num_train_epochs=3, + per_device_train_batch_size=4, # SFT에서는 배치 크기를 줄일 수 있음 + gradient_accumulation_steps=8, + learning_rate=2e-5, + warmup_ratio=0.03, # 예시 + lr_scheduler_type="cosine", + logging_steps=10, + save_strategy="epoch", # 또는 save_steps + fp16=True, # 혼합 정밀도 + # ... 기타 SFT 관련 인자들 +) + +trainer = Trainer( + model=model, + args=training_args, + train_dataset=sft_train_dataset, # 전처리된 SFT 학습 데이터셋 + eval_dataset=sft_eval_dataset, # 전처리된 SFT 평가 데이터셋 (선택 사항) + data_collator=data_collator_sft, # SFT용 데이터 콜레이터 (labels 마스킹 처리 포함) +) + +trainer.train() +trainer.save_model() # 미세조정된 모델 저장 +tokenizer.save_pretrained(training_args.output_dir) # 토크나이저 저장 +``` + +### 5.4. SFT 실행 예시 명령어 (개념적) + +가상의 SFT 학습 스크립트 `train_sft.py`가 있다고 가정할 때 실행 명령어는 다음과 같을 수 있습니다: + +```bash +python train_sft.py \ + --model_name_or_path "path/to/pretrained_bitnet_model_checkpoint" \ + --tokenizer_name "path/to/pretrained_bitnet_model_checkpoint" \ + --train_file "path/to/korean_sft_data_train.jsonl" \ + --output_dir "./sft_bitnet_korean_model" \ + --num_train_epochs 3 \ + --per_device_train_batch_size 4 \ + --learning_rate 2e-5 \ + --fp16 \ + # ... 기타 인자들 +``` + +## 6. 선호도 최적화 (DPO - Direct Preference Optimization) + +SFT 이후 모델의 응답을 인간의 선호도에 더욱 가깝게 정렬하기 위한 추가적인 단계로 DPO(Direct Preference Optimization)를 고려할 수 있습니다. DPO는 SFT된 모델을 기반으로 추가적인 미세조정을 수행합니다. + +* **목표**: 모델이 인간이 선호하는 응답 스타일, 내용, 안전성 등을 갖도록 학습합니다. +* **데이터셋**: DPO는 프롬프트(prompt)와 함께 인간이 더 선호하는 응답(chosen response)과 덜 선호하는 응답(rejected response) 쌍으로 구성된 데이터셋을 사용합니다. + * 예시 데이터 형식: + ```json + {"prompt": "대한민국에서 가장 높은 산은 무엇인가요?", "chosen_response": "대한민국에서 가장 높은 산은 제주도에 위치한 한라산입니다.", "rejected_response": "음... 아마 설악산일 겁니다. 확실하지는 않아요."} + ``` +* **학습 방식**: DPO는 보상 모델(Reward Model)을 명시적으로 학습할 필요 없이, 선호도 데이터를 사용하여 직접적으로 언어 모델을 최적화합니다. 이는 RLHF(Reinforcement Learning from Human Feedback)의 복잡성을 줄이면서도 유사한 효과를 얻을 수 있는 방법으로 주목받고 있습니다. +* **구현**: DPO 학습을 위해서는 `trl` (Transformer Reinforcement Learning) 라이브러리의 `DPOTrainer`와 같은 특화된 도구나 직접 구현이 필요할 수 있습니다. + +DPO는 SFT 이후 모델의 품질을 한 단계 더 끌어올릴 수 있는 고급 튜닝 기법입니다. + +## 7. 평가 +(기존 섹션 5. 평가 내용을 이쪽으로 이동 또는 유지) SFT된 한국어 BitNet 모델의 성능은 수행하려는 특정 작업에 따라 평가됩니다. * **자동 평가 지표:** @@ -80,8 +230,17 @@ SFT된 한국어 BitNet 모델의 성능은 수행하려는 특정 작업에 따 * **인간 평가:** 특히 개방형 질문 답변, 창의적 텍스트 생성, 대화 능력 등과 같이 자동 평가가 어려운 작업의 경우, 인간 평가자가 모델 출력의 품질, 관련성, 유창성 등을 직접 평가하는 것이 중요합니다. * **벤치마크 데이터셋:** 공개된 한국어 LLM 평가 벤치마크(예: KLUE, KoBEST 등)를 사용하여 다른 모델과 성능을 비교할 수 있습니다. -## 6. 결론 - +## 8. 결론 +(기존 섹션 6. 결론 내용을 이쪽으로 이동 또는 유지) 한국어 BitNet 언어 모델의 SFT는 사전 학습된 모델의 효율성을 유지하면서 특정 작업에 대한 성능을 극대화하는 것을 목표로 합니다. 이 과정에서는 BitNet 고유의 3진 가중치 특성을 고려한 학습 전략과 고품질의 한국어 지시-응답 데이터셋이 핵심적인 역할을 합니다. 본 문서는 일반적인 SFT 원칙과 BitNet 아키텍처의 특성을 결합하여 한국어 BitNet 모델의 SFT에 대한 개괄적인 지침을 제공합니다. 그러나 BitNet 모델을 위한 최적의 SFT 방법론과 구체적인 절차는 모델 개발자가 제공하는 공식 문서나 관련 연구 논문을 통해 확인하는 것이 가장 정확합니다. 특히 SFT 중 가중치 처리 방식과 같은 핵심적인 세부 사항은 공식적인 정보가 중요합니다. + +## 참고 자료 (References) + +* **tinyllama-bitnet GitHub Repository:** [pranavjad/tinyllama-bitnet](https://github.com/pranavjad/tinyllama-bitnet) - 본 문서에서 많은 코드 예시와 학습 절차 아이디어를 참조한 저장소입니다. +* **The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits (BitNet b1.58):** [arXiv:2402.17764](https://arxiv.org/abs/2402.17764) - 1.58비트 BitNet에 대한 핵심 논문입니다. +* **BitNet: Scaling 1-bit Transformers for Large Language Models (Original BitNet):** [arXiv:2310.11453](https://arxiv.org/abs/2310.11453) - 초기 1비트 BitNet 아키텍처에 대한 논문입니다. +* **The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ.pdf:** [Microsoft UniLM GitHub](https://github.com/microsoft/unilm/blob/master/bitnet/The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ.pdf) - Microsoft에서 제공하는 BitNet 학습 팁 및 FAQ 문서입니다. +* **microsoft/BitNet (bitnet.cpp):** [GitHub](https://github.com/microsoft/BitNet) - BitNet 모델을 위한 공식 C++ 추론 프레임워크 저장소입니다. +* **Hugging Face TRL (Transformer Reinforcement Learning):** [GitHub](https://github.com/huggingface/trl) - DPO(Direct Preference Optimization)와 같은 선호도 튜닝 기법을 구현하는 데 유용한 라이브러리입니다. (SFT-Tuning.md에 특히 관련)