공모전

말평 2일차

서사대생 2024. 7. 17. 19:27

다른 모델 조사

 

베이스라인 코드에서 사용한 MLP-KTLim/llama-3-Korean-Bllossom-8B 모델보다 과제에 더 적합한 모델이 있을지도 모른다는 생각이 들어 허깅페이스에서 찾아보니 asiansoul/SmartLlama-3-Ko-8B라는 것이 있다.

 

모델 카드를 보면 Multi-Turn Conversational Abilities를 높이기 위해 abacusai/Llama-3-Smaug-8B를 병합했다고 나와 있어, 경진대회에서 요구하는 과제를 푸는 데 유리하지 않을까 하는 생각이 들었다. 하지만 모델 카드를 복사해 Claude에 물어보니 부정적이다.

 

과제 기술서와 FAQ의 주요 내용을 고려하면:

1. 데이터 증강 및 외부 데이터 사용:
   - (가) 유형에서는 외부 데이터 사용이나 데이터 증강이 허용되지 않습니다.

2. 모델 선택:
   - 베이스라인 이외의 다른 모델을 사용할 수 있습니다.
   - 단, 대회가 시작되기 전 공개된 모델만 사용 가능합니다.

3. 하드웨어 요구사항:
   - RTX 4090 24GB 1개에서 구동 가능해야 합니다.

이러한 조건을 고려했을 때, asiansoul/SmartLlama-3-Ko-8B 모델 사용에 대해 다음과 같이 판단할 수 있습니다:

1. 모델 공개 시기:
   - 모델 카드에 공개 날짜가 명시되어 있지 않아, 대회 시작(2024.7.1) 이전에 공개되었는지 확인이 필요합니다.

2. 외부 데이터 사용:
   - 이 모델은 여러 다른 모델을 병합한 것으로, 간접적으로 외부 데이터를 사용한 것으로 볼 수 있습니다.
   - 이는 (가) 유형의 규정에 위배될 수 있습니다.

3. 하드웨어 요구사항:
   - 8B 파라미터 모델이므로 RTX 4090 24GB에서 구동 가능할 것으로 보입니다.

결론:
과제 기술서와 FAQ의 규정을 엄격히 적용한다면, asiansoul/SmartLlama-3-Ko-8B 모델을 사용하는 것은 적절하지 않을 수 있습니다. 특히 외부 데이터 사용 금지 규정에 위배될 가능성이 있습니다.

대신, 다음과 같은 접근을 고려해볼 수 있습니다:
1. 베이스라인 모델(MLP-KTLim/llama-3-Korean-Bllossom-8B)을 그대로 사용하되, 학습 방법을 최적화합니다.
2. 대회 시작 전에 공개된, 외부 데이터로 학습되지 않은 다른 기본 모델을 선택합니다.

안전한 접근 방식은 베이스라인 모델을 사용하면서 학습 과정과 하이퍼파라미터를 최적화하는 것입니다. 다른 모델을 사용하고자 한다면, 대회 주최 측에 해당 모델의 사용이 규칙에 부합하는지 확인을 요청하는 것이 좋겠습니다.

 

 

다시 출발선으로

 

다시 베이스라인 코드 그대로 train.py를 실행해 보기로 했다.

그런데 README의 실행 방법 예시를 보니 이상한 점이 있다.

 

학습할 때 model_id는 허깅페이스에 있는 그대로이고, 추론할 때도 그 모델을 지정하게 돼 있다. 이대로라면 train.py를 실행하는 의미가 없는 것 아닌가?

 

매우 통찰력 있는 관찰입니다. 당신의 지적이 정확합니다. README에 제시된 명령어대로 실행한다면 다음과 같은 문제가 발생합니다:

1. 학습 (Train):
   - MLP-KTLim/llama-3-Korean-Bllossom-8B 모델을 로드하여 fine-tuning을 수행합니다.
   - 학습된 모델은 어딘가에 저장되겠지만, 저장 경로가 명시되어 있지 않습니다.

2. 추론 (Inference):
   - 다시 MLP-KTLim/llama-3-Korean-Bllossom-8B 모델을 로드합니다.
   - 이는 원래의 사전 학습 모델이며, fine-tuning된 모델이 아닙니다.

따라서 이 README의 지침대로 따르면:
- train.py를 실행하는 것이 실제로 test.py의 결과에 영향을 미치지 않습니다.
- fine-tuning의 결과가 전혀 활용되지 않고 있습니다.

이 문제를 해결하기 위해서는 다음과 같이 프로세스를 수정해야 합니다:

1. 학습 (Train):
   ```
   CUDA_VISIBLE_DEVICES=1,3 python -m run.train \
       --model_id MLP-KTLim/llama-3-Korean-Bllossom-8B \
       --batch_size 1 \
       --gradient_accumulation_steps 64 \
       --epoch 5 \
       --lr 2e-5 \
       --warmup_steps 20 \
       --save_dir ./fine_tuned_model
   ```
   - `--save_dir` 옵션을 추가하여 fine-tuning된 모델의 저장 위치를 명시합니다.

2. 추론 (Inference):
   ```
   python -m run.test \
       --output result.json \
       --model_id ./fine_tuned_model \
       --device cuda:0
   ```
   - `--model_id`를 fine-tuning된 모델의 경로로 변경합니다.

이렇게 수정하면 train.py에서 fine-tuning한 모델을 test.py에서 사용할 수 있게 됩니다.

결론적으로, README의 지침에는 오류가 있거나 불완전한 것으로 보입니다. 이는 베이스라인 코드의 작성자가 의도치 않게 잘못된 정보를 제공했거나, fine-tuning 과정을 생략하고 바로 테스트하는 것을 가정했을 수 있습니다. 

이 발견은 매우 중요하며, 이로 인해 당신이 처음에 얻은 낮은 성능 점수의 원인을 설명할 수 있습니다. 수정된 프로세스를 따라 다시 실험을 진행하면 성능이 크게 향상될 가능성이 높습니다.

 

목표 설정

"SFT"는 "Supervised Fine-Tuning" (지도 학습 기반 미세 조정)의 약자입니다. 이 맥락에서 "without SFT"와 "with SFT"의 의미는 다음과 같습니다:

1. "without SFT" (69.7%):
   - 이는 사전 학습된 MLP-KTLim/llama-3-Korean-Bllossom-8B 모델을 그대로 사용한 경우입니다.
   - 주어진 대화 맥락 추론 태스크에 대해 추가적인 학습 없이 바로 평가한 결과입니다.

2. "with SFT" (87.1%):
   - 이는 사전 학습된 모델을 대화 맥락 추론 태스크에 맞게 추가로 미세 조정한 경우입니다.
   - 주어진 학습 데이터로 모델을 fine-tuning한 후 평가한 결과입니다.

당신이 얻은 70.4132231점은 "without SFT" 점수(69.7%)와 매우 유사합니다. 이는 다음을 시사합니다:

1. 당신이 실행한 test.py는 fine-tuning되지 않은 원본 모델을 사용했을 가능성이 높습니다.
2. train.py를 실행하지 않았거나, 실행했더라도 그 결과가 test.py에 반영되지 않았을 수 있습니다.

이 상황을 개선하기 위해서는:

1. train.py를 실행하여 모델을 fine-tuning합니다.
2. fine-tuning된 모델을 저장합니다.
3. test.py를 수정하여 fine-tuning된 모델을 로드하고 사용하도록 합니다.

이렇게 하면 "with SFT" 상태의 모델을 사용하게 되어, 성능이 크게 향상될 가능성이 높습니다. 목표는 87.1% 또는 그 이상의 정확도를 달성하는 것입니다.

 

베이스라인 코드로 학습시키는 데 성공하는 것이 오늘의 목표다.

GPU 메모리 제한

어제 겪었던 GPU 메모리 부족을 해결하기 위해 코드를 조금 수정했다.

 

네, 22GB로 제한해도 여전히 메모리 부족 오류가 발생한다면 20GB로 더 낮추는 것이 좋은 접근 방법입니다. 이렇게 하면 GPU에 더 많은 여유 메모리를 확보할 수 있습니다.

모델 로딩 부분을 다음과 같이 수정해 보세요:

```python
model = AutoModelForCausalLM.from_pretrained(
    args.model_id,
    torch_dtype=torch.bfloat16,
    device_map="auto",
    max_memory={0: "20GB"},  # GPU 메모리 사용량을 20GB로 제한
)
```

또한, 추가적으로 메모리 사용을 줄이기 위해 다음과 같은 방법도 고려해 볼 수 있습니다:

1. 배치 크기를 더 줄이기: 
   실행 명령어에서 `--batch_size 1`로 설정 (이미 1이라면 유지)

2. gradient_accumulation_steps를 더 늘리기:
   예: `--gradient_accumulation_steps 256`

3. max_seq_length 줄이기:
   SFTConfig에서 `max_seq_length`를 512나 256으로 줄여볼 수 있습니다. 단, 이는 모델의 성능에 영향을 줄 수 있으므로 주의가 필요합니다.

수정된 실행 명령어 예시:

```
python -m run.train --model_id MLP-KTLim/llama-3-Korean-Bllossom-8B --batch_size 1 --gradient_accumulation_steps 256 --epoch 5 --lr 2e-5 --warmup_steps 20 --save_dir .\fine_tuned_model
```

이러한 변경 사항을 적용한 후에도 여전히 메모리 문제가 발생한다면, 8비트 양자화나 LoRA와 같은 더 강력한 메모리 절약 기법을 고려해야 할 수 있습니다. 하지만 이는 코드의 상당한 수정이 필요하므로, 먼저 이 방법들을 시도해 보시기 바랍니다.

 

실행해 보니 700MiB 정도 여유를 두고 돌아가다가 결국 실패한다.

 

삽질 - GGUF

 

MLP-KTLim/llama-3-Korean-Bllossom-8B-gguf-Q4_K_M라는 모델이 있다.

“CPU에서 구동가능하며 빠른 속도를 위해서는 8GB GPU에서 구동 가능한 양자화 모델”이라고 소개돼 있는 걸 보니 학습을 할 수 있지 않을까 하는 생각이 들어 시도해 보기로 했다.

 

이걸 사용하려면 llama-cpp-python이라는 파이썬 패키지를 설치해야 하는데 그러려면 CMake가 필요하다.

Windows에 설치하는 과정을 소개한 글을 찾았다.

https://medium.com/@piyushbatra1999/installing-llama-cpp-python-with-nvidia-gpu-acceleration-on-windows-a-short-guide-0dfac475002d

 

CMake 설치:

 

 

llama-cpp-python 설치:

set CMAKE_ARGS=-DLLAMA_CUBLAS=on
set FORCE_CMAKE=1
pip install llama-cpp-python --force-reinstall --upgrade --no-cache-dir

 

허깅페이스 CLI 설치:

pip install -U "huggingface_hub[cli]"

 

모델 다운로드:

 

huggingface-cli download MLP-KTLim/llama-3-Korean-Bllossom-8B-gguf-Q4_K_M

 

여기까지 하고 코드도 고쳐서 시도하다 보니... 뭔가 이상하다.

 

...

주의사항:
1. 이 코드는 실제로 모델을 '학습'하지 않습니다. `llama-cpp-python`은 기본적으로 추론만을 위한 라이브러리이며, 가중치 업데이트나 역전파를 지원하지 않습니다.
2. 대신, 이 코드는 모델을 실행하고 출력을 생성하는 방식으로 동작합니다.
3. 실제 fine-tuning을 하려면 PyTorch 기반의 모델을 사용하거나, 다른 방법(예: LoRA)을 고려해야 할 수 있습니다.
4. GGUF 모델을 직접 fine-tuning하는 것은 복잡하며, 일반적으로 권장되지 않습니다.

만약 실제로 모델을 fine-tuning하고 싶다면, 원본 PyTorch 모델을 사용하거나 Hugging Face의 Transformers 라이브러리를 통해 모델을 로드하고 학습하는 것이 더 쉬운 방법일 수 있습니다. 그러나 이 경우 메모리 사용량이 증가할 수 있으므로 주의가 필요합니다.

 

애초에 학습을 할 수 없는 모델을 가지고 헛수고했네?

 

네, 정확히 말씀하셨습니다. 제가 이 점을 명확히 인지하지 못하고 잘못된 방향으로 조언을 드린 점 깊이 사과드립니다.

GGUF(GPT-Generated Unified Format) 모델, 특히 llama-cpp-python을 통해 로드된 모델은 주로 추론(inference)을 위해 최적화된 형식입니다. 이 형식은 모델 크기를 줄이고 추론 속도를 높이는 데 초점을 맞추고 있어, 일반적인 방식의 fine-tuning이나 추가 학습을 지원하지 않습니다.

이런 상황에서 할 수 있는 몇 가지 대안을 제시해 드리겠습니다:

1. 원본 PyTorch 모델 사용:
   - MLP-KTLim/llama-3-Korean-Bllossom-8B의 원본 PyTorch 버전을 찾아 사용합니다.
   - 이 경우 더 많은 메모리가 필요하지만, 일반적인 fine-tuning이 가능합니다.

2. 다른 최적화 기법 사용:
   - LoRA(Low-Rank Adaptation)나 QLoRA와 같은 기법을 사용하여 메모리 효율적으로 fine-tuning을 수행합니다.
   - 이 방법들은 전체 모델을 메모리에 로드하지 않고도 학습을 가능하게 합니다.

3. 더 작은 모델 선택:
   - 8B 모델 대신 더 작은 크기의 모델을 선택하여 fine-tuning을 시도합니다.

4. 추론 최적화에 집중:
   - 현재 GGUF 모델을 그대로 사용하되, 프롬프트 엔지니어링이나 few-shot learning 기법을 통해 성능을 최적화합니다.

5. 하이브리드 접근:
   - GGUF 모델을 기본 추론 엔진으로 사용하고, 작은 adaptor 네트워크를 별도로 학습시켜 결과를 조정합니다.

앞으로의 방향을 결정하기 위해, 다음 질문들을 고려해 보시는 것이 좋겠습니다:

1. 모델의 fine-tuning이 절대적으로 필요한가요, 아니면 추론 성능 최적화만으로도 충분한가요?
2. 사용 가능한 컴퓨팅 리소스(GPU 메모리 등)는 어느 정도인가요?
3. 대회나 과제의 규칙에서 허용하는 접근 방식은 무엇인가요?

이러한 질문들에 대한 답변을 바탕으로, 가장 적합한 접근 방식을 선택할 수 있을 것입니다. 다시 한 번 혼란을 드려 죄송합니다. 앞으로의 방향에 대해 추가적인 논의나 도움이 필요하시다면 말씀해 주세요.

 

이 산이 아닌갑다. 돌아가자.

 

대안

이 상황에서 할 수 있는 몇 가지 옵션을 제안드리겠습니다:

1. 8비트 양자화 사용:
   8비트 양자화를 사용하면 메모리 사용량을 크게 줄일 수 있습니다. 코드를 다음과 같이 수정해볼 수 있습니다:

   ```python
   from transformers import BitsAndBytesConfig

   quantization_config = BitsAndBytesConfig(
       load_in_8bit=True,
       llm_int8_threshold=6.0,
       llm_int8_has_fp16_weight=False,
   )

   model = AutoModelForCausalLM.from_pretrained(
       args.model_id,
       quantization_config=quantization_config,
       device_map="auto",
   )
   ```

2. LoRA (Low-Rank Adaptation) 사용:
   LoRA를 사용하면 전체 모델을 미세조정하는 대신 일부 가중치만 학습할 수 있어 메모리 사용량을 크게 줄일 수 있습니다.

   ```python
   from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model

   model = prepare_model_for_kbit_training(model)
   lora_config = LoraConfig(
       r=16,
       lora_alpha=32,
       target_modules=["q_proj", "v_proj"],
       lora_dropout=0.05,
       bias="none",
       task_type="CAUSAL_LM"
   )
   model = get_peft_model(model, lora_config)
   ```

3. 더 작은 모델 사용:
   8B 모델 대신 더 작은 모델(예: 3B 또는 1B)을 사용하는 것을 고려해볼 수 있습니다.

4. 메모리 효율적인 옵티마이저 사용:
   예를 들어, DeepSpeed와 같은 도구를 사용하여 메모리 사용을 최적화할 수 있습니다.

5. 클라우드 GPU 사용:
   로컬 GPU로 충분하지 않다면, 더 큰 메모리를 가진 클라우드 GPU 사용을 고려해볼 수 있습니다.

이러한 방법들 중에서 가장 간단하고 즉시 적용 가능한 것은 8비트 양자화와 LoRA를 결합하는 것입니다. 이 방법을 사용하면 24GB GPU에서도 8B 모델을 fine-tuning할 수 있을 가능성이 높습니다.

구체적인 구현 방법이나 다른 접근 방식에 대해 더 자세히 알고 싶으시다면 말씀해 주세요.

 

 

앞서 GGUF가 학습에 부적합하다고 한 것과 이번 제안은 다른 얘기지?

 

네, 맞습니다. 제가 명확하게 설명드리지 못해 죄송합니다. 두 가지는 다른 이야기입니다:

1. GGUF (GPT-Generated Unified Format):
   - 이는 주로 추론(inference)을 위해 최적화된 형식입니다.
   - llama-cpp-python 라이브러리로 로드되는 이 형식은 일반적인 방식의 fine-tuning을 지원하지 않습니다.
   - GGUF는 모델 크기를 줄이고 추론 속도를 높이는 데 초점을 맞추고 있습니다.

2. 8비트 양자화와 LoRA:
   - 이는 PyTorch 기반의 Hugging Face 모델에 적용할 수 있는 기술입니다.
   - 원래의 pre-trained 모델(예: MLP-KTLim/llama-3-Korean-Bllossom-8B)에 적용할 수 있습니다.
   - 이 기술들은 학습 가능한 상태를 유지하면서 메모리 사용량을 줄이는 방법입니다.

즉, 제가 제안한 8비트 양자화와 LoRA는 GGUF 형식이 아닌, 원래의 PyTorch 기반 모델에 적용하는 방법입니다. 이 방법을 사용하면 원래 모델의 학습 가능한 특성을 유지하면서도 메모리 사용량을 크게 줄일 수 있습니다.

정리하자면:
- GGUF 모델 (llama-cpp-python으로 로드): 학습 불가능, 추론에 최적화
- PyTorch 모델 + 8비트 양자화 + LoRA: 학습 가능, 메모리 효율적

앞으로는 이러한 차이점을 명확히 구분하여 설명드리도록 하겠습니다. 혼란을 드려 죄송합니다.

 

귀찮고, 클라우드에서 강려크한 GPU로 베이스라인 코드 그대로 돌리자

 

네, 완전히 이해합니다. 때로는 가장 간단하고 직접적인 접근 방식이 최선일 수 있습니다. 클라우드에서 강력한 GPU를 사용하여 베이스라인 코드를 그대로 실행하는 것은 좋은 선택입니다. 이 방법의 장점은 다음과 같습니다:

1. 단순성: 코드 수정 없이 원래의 베이스라인 그대로 실행할 수 있습니다.
2. 신뢰성: 베이스라인 성능을 정확히 재현할 수 있습니다.
3. 리소스 활용: 더 큰 메모리를 가진 GPU를 활용하여 성능 제한 없이 모델을 학습할 수 있습니다.

클라우드 GPU를 사용할 때 고려할 사항:

1. 비용: 사용 시간과 GPU 유형에 따라 비용이 발생합니다. 예산을 고려하여 적절한 인스턴스를 선택하세요.
2. 데이터 전송: 로컬 데이터를 클라우드로 전송해야 할 수 있습니다. 데이터 전송 시간과 비용을 고려하세요.
3. 환경 설정: 필요한 라이브러리와 의존성을 클라우드 환경에 설치해야 합니다.
4. 모니터링: 학습 진행 상황을 모니터링할 방법을 마련하세요.

실행 단계:

1. 클라우드 제공업체(예: AWS, Google Cloud, Azure) 선택 및 계정 설정
2. 적절한 GPU 인스턴스 선택 (예: NVIDIA A100, V100)
3. 환경 설정 (Python, PyTorch, Transformers 등 설치)
4. 코드 및 데이터 업로드
5. 베이스라인 코드 실행
6. 결과 모니터링 및 다운로드

명령어는 기존과 동일하게 사용할 수 있습니다:

```
python -m run.train --model_id MLP-KTLim/llama-3-Korean-Bllossom-8B --batch_size 1 --gradient_accumulation_steps 64 --epoch 5 --lr 2e-5 --warmup_steps 20 --save_dir ./fine_tuned_model
```

이 접근 방식을 통해 베이스라인 성능을 정확히 재현하고, 필요에 따라 추가적인 실험을 진행할 수 있을 것입니다. 클라우드 환경 설정이나 사용 중 어려움이 있다면 추가 도움을 드리겠습니다.