AI 또는 풀스택 개발에 어려움을 겪고 계신가요? 맞춤형 조언, 기술 통합 등 유니티 전문가가 도와드리겠습니다. 다음 연락처로 문의하세요. [email protected].

GPU 또는 TPU에서 JAX를 사용하여 LLaMA, OpenLLaMA 및 XGen을 미세 조정하는 방법

LLaMA, OpenLLaMA, XGen은 최첨단 제너레이티브 AI 모델입니다. 이러한 모델은 자체 데이터에 대해 미세 조정할 때 훨씬 더 나은 결과를 제공합니다. 이 글에서는 JAX와 EasyLM 라이브러리를 사용하여 GPU와 TPU 모두에서 이러한 모델을 미세 조정하는 방법을 살펴보겠습니다.

LLaMA, OpenLLaM 및 XGen

메타는 2023년 2월에 LLaMA 모델을 출시했습니다. 이 생성형 AI 모델은 여러 가지 크기로 제안된 오픈 소스 모델입니다: 7억 개의 매개변수, 13억 개의 매개변수, 33억 개의 매개변수, 65억 개의 매개변수입니다.

2021년 6월 GPT-J가 출시되었을 때, 전 세계는 오픈소스 제너레이티브 AI 모델이 OpenAI GPT-3와 진지하게 경쟁할 수 있다는 것을 깨닫기 시작했습니다. 이제 LLaMA를 통해 그 기준이 다시 한 번 높아졌으며, 이 모델은 OpenAI ChatGPT 및 GPT-4에 대한 매우 훌륭한 오픈소스 대안이 될 것으로 보입니다.

이 모델은 상업적 목적으로는 사용할 수 없습니다. 하지만 좋은 소식은 다른 모델이 존재한다는 것입니다.

2023년 6월에 출시된 OpenLLaMA는 버클리 인공지능 연구팀에서 개발한 LLaMA의 대체 버전으로, 매우 우수한 결과를 제공하며 비즈니스에 사용할 수 있습니다. 이 글을 쓰는 현재 두 가지 버전이 제공됩니다: 7B 파라미터와 13B 파라미터입니다.

2023년 6월에 Salesforce에서 출시한 XGen은 상용 애플리케이션에서 사용할 수 있는 매우 강력한 또 다른 기본 모델입니다. 이 글을 쓰는 현재 7B 매개변수 버전만 사용할 수 있습니다. 이 모델은 8k 토큰 컨텍스트를 지원하는 반면, LLaMA와 OpenLLaMA는 2k 토큰 콘텐츠만 지원한다는 점에 주목할 필요가 있습니다.

나만의 모델을 미세 조정하는 이유는 무엇인가요?

위의 모델은 기초 모델로서, 대규모 텍스트 말뭉치에 대해 비지도 방식으로 학습된 모델입니다.

이러한 기본 AI 모델은 일반적으로 좋은 기반이 되지만 원하는 것을 제대로 이해하고 좋은 결과를 반환하려면 조정이 필요합니다. 이를 달성하는 가장 쉬운 방법은 '프롬프트 엔지니어링'이라고도 하는 단발성 학습을 사용하는 것입니다. 여기에서 몇 컷 학습 가이드를 읽어보세요.

몇 번의 샷 학습은 새로운 버전의 생성 AI 모델을 만들지 않고도 즉시 수행할 수 있어 편리하지만 때로는 충분하지 않을 수 있습니다.

최첨단 결과를 얻으려면 자신의 사용 사례에 맞게 AI 모델을 미세 조정해야 합니다. 미세 조정이란 자체 데이터를 기반으로 모델의 일부 매개 변수를 수정한 다음 자신만의 모델 버전을 얻는 것을 의미합니다.

미세 조정은 생성형 AI 모델을 처음부터 훈련하는 것보다 훨씬 저렴하지만 여전히 계산 능력이 필요하므로 모델을 미세 조정하려면 고급 하드웨어가 필요합니다. 최근의 일부 대체 미세 조정 기법에는 연산 능력이 덜 필요하지만(p-튜닝, 프롬프트 튜닝, 소프트 튜닝, 파라미터 효율적 미세 조정, 어댑터, LoRA, QLoRA 참조), 지금까지 이러한 기법으로 동일한 수준의 품질을 얻지 못했기 때문에 이 튜토리얼에서는 언급하지 않기로 하겠습니다.

JAX 및 EasyLM으로 TPU에서 LLaMA 미세 조정하기

이 튜토리얼에서는 버클리 AI 연구팀에서 출시한 EasyLM 라이브러리를 사용하여 LLaMA를 미세 조정하는 방법에 중점을 둡니다: https://github.com/young-geng/EasyLM. This library is based on JAX which makes the fine-tuning process fast and compatible with both GPUs and Google TPUs.

동일한 기술을 사용하여 OpenLLaMA 또는 XGen을 미세 조정할 수도 있습니다.

여기서는 Google TPU V3-8에서 LLaMA 7B를 미세 조정했지만, A100 GPU에서도 완벽하게 동일한 작업을 수행할 수 있습니다(약간 다른 EasyLM 설명서의 "설치" 부분을 주의 깊게 읽어보시기만 하면 됩니다). 물론 더 큰 버전의 LLaMA(13B, 33B, 65B...)도 미세 조정할 수 있지만 TPU V3-8 또는 단일 A100 GPU보다 훨씬 더 많은 것이 필요합니다.

여기 있습니다!

먼저, 각 예제의 키로 'text'를 사용하여 사용 사례에 대한 텍스트 생성 데이터 집합을 JSONL 형식으로 만듭니다. 다음은 간단한 감성 분석 데이터 세트입니다:

{"text":"[Content]: I love NLP Cloud, this company is awesome!\n[Sentiment]: Positive"}
{"text":"[Content]: Training LLMs is a complex but rewarding process.\n[Sentiment]: Neutral"}
{"text":"[Content]: My fine-tuning keeps crashing because of an OOM error! It just does not work at all!\n[Sentiment]: Negative"}

몇 가지 중요한 사항에 유의하시기 바랍니다. 첫째, 이 데이터 세트에는 단순화를 위해 3개의 예제만 포함되어 있지만 실제로는 더 많은 예제가 필요할 것입니다. 일반적으로 300개의 예가 좋은 시작입니다. 둘째, 추론에 미세 조정된 모델을 사용할 때는 '[Content]:' 및 '[Sentiment]:' 접두사를 사용하여 동일한 형식을 엄격하게 따라야 합니다. 마지막으로, "</s>" 토큰은 여기서 모델 생성을 중지해야 함을 의미하므로 중요합니다. 더 많은 데이터 세트 예제는 NLP Cloud 문서에서 찾을 수 있습니다: 여기에서 자세히 알아보세요.

V2 알파 소프트웨어 버전으로 Google Cloud에서 TPU V3-8 VM을 생성합니다:

가상 머신에 SSH로 접속하여 EasyLM을 설치합니다:

git clone https://github.com/young-geng/EasyLM
cd EasyLM
bash ./scripts/tpu_vm_setup.sh

이제 LLaMA 가중치를 다운로드하여 변환할 수 있습니다. 첫 번째 옵션은 메타에 공식 가중치를 요청하는 것입니다: https://ai.facebook.com/blog/large-language-model-llama-meta-ai/. 그런 다음 이 스크립트를 사용하여 가중치를 EasyLM으로 변환합니다: https://github.com/young-geng/EasyLM/blob/main/EasyLM/models/llama/convert_torch_to_easylm.py. 두 번째 옵션은 HuggingFace에서 LLaMA 가중치를 사용하는 것입니다: https://huggingface.co/decapoda-research/llama-7b-hf. 그런 다음 이 스크립트를 사용하여 가중치를 EasyLM으로 변환합니다: https://github.com/young-geng/EasyLM/blob/main/EasyLM/models/llama/convert_hf_to_easylm.py.

데이터세트를 VM에 업로드하고, HF LLaMA 토큰라이저를 사용하여 포함된 토큰의 수를 계산합니다:

pip install -U transformers
python -c "from transformers import LlamaTokenizer; tokenizer = LlamaTokenizer.from_pretrained('decapoda-research/llama-7b-hf'); f = open('/path/to/your/dataset', 'r'); print(len(tokenizer.encode(f.read())))"

1024개의 토큰 컨텍스트에 대해 모델을 학습시키는 경우 반환된 토큰 수를 1024로 나누어야 합니다.

2048개의 토큰 컨텍스트에 대해 모델을 학습시키는 경우 반환된 토큰 수를 2048개로 나누어야 합니다.

이 숫자는 에포크당 걸음 수입니다. 예를 들어 5개의 에포크(일반적으로 좋은 설정)를 훈련하려면 이 숫자에 5를 곱하고 그 결과 값을 아래의 --total_steps에 입력해야 합니다.

구체적인 예를 들면, 데이터 집합에 100,000개의 토큰이 포함되어 있고 1024개의 토큰 컨텍스트와 5개의 에포크가 필요한 경우 총 단계 수는 (100,000/1024)*5 = 488개가 됩니다.

컨텍스트 길이에 따라 아래에서 --train_dataset.json_dataset.seq_length를 1024 또는 2048로 설정합니다. 2048 토큰 컨텍스트에 맞게 모델을 미세 조정하려면 더 많은 메모리가 필요하므로 꼭 필요한 경우가 아니라면 1024 토큰 컨텍스트를 사용하는 것이 좋습니다.

이제 미세 조정 프로세스를 시작할 수 있습니다:

nohup python -u EasyLM/EasyLM/models/llama/llama_train.py \
--total_steps=your number of steps \
--save_model_freq=usually same as your number of steps \
--optimizer.adamw_optimizer.lr_warmup_steps=usually 10% of total steps \
--train_dataset.json_dataset.path='/path/to/your/dataset' \
--train_dataset.json_dataset.seq_length=1024 or 2048 \
--load_checkpoint='params::/path/to/converted/model' \
--tokenizer.vocab_file='/path/to/tokenizer' \
--logger.output_dir=/path/to/output  \
--mesh_dim='1,4,2' \
--load_llama_config='7b' \
--train_dataset.type='json' \
--train_dataset.text_processor.fields='text' \
--optimizer.type='adamw' \
--optimizer.accumulate_gradient_steps=1 \
--optimizer.adamw_optimizer.lr=0.002 \
--optimizer.adamw_optimizer.end_lr=0.002 \
--optimizer.adamw_optimizer.lr_decay_steps=100000000 \
--optimizer.adamw_optimizer.weight_decay=0.001 \
--optimizer.adamw_optimizer.multiply_by_parameter_scale=True \
--optimizer.adamw_optimizer.bf16_momentum=True &

몇 가지 설명이 있습니다:

--save_model_freq: 프로세스 중에 모델을 저장할 빈도. 작은 데이터 세트에 대해서만 미세 조정하는 경우 프로세스가 끝날 때만 저장할 수 있으며, 이 경우 이 값은 --total_steps와 같게 됩니다.

--optimizer.adamw_optimizer.lr_warmup_steps: 일반적으로 총 걸음 수의 10%가 좋은 값입니다.

--토큰라이저.vocab_file: 토큰라이저.모델 파일의 경로입니다. 예를 들어 HuggingFace에서 데카포다 리포지토리를 사용하는 경우 토큰라이저에 대한 링크는 다음과 같습니다: https://huggingface.co/decapoda-research/llama-7b-hf/resolve/main/tokenizer.model.

--logger.output_dir: 최종 모델 및 로그의 경로

다른 매개변수는 그대로 둘 수 있습니다.

미세 조정 프로세스가 완료되면 --logger.output_dir에 지정한 경로에서 모델을 검색할 수 있습니다.

추론을 위해 미세 조정된 모델 사용

이제 자신만의 미세 조정된 모델이 생겼으니 당연히 사용하고 싶을 것입니다!

첫 번째 전략은 추론에 EasyLM 라이브러리를 사용하는 것입니다. 이 경우 다음과 같이 추론 서버를 시작할 수 있습니다:

python EasyLM/EasyLM/models/llama/llama_serve.py  \
--mesh_dim='1,1,-1' \
--load_llama_config='7b' \
--load_checkpoint='params::/path/to/your/model' \
--tokenizer.vocab_file='/path/to/tokenizer'

그런 다음 다음과 같이 cURL을 사용하여 요청을 보내면 됩니다:

curl "http://0.0.0.0:5007/generate" \
-H "Content-Type: application/json" \
-X POST -d '{"prefix_text":["[Content]: EasyLM works really well!\n[Sentiment]:"]}'

두 번째 전략은 다른 프레임워크에서 추론을 수행하기 위해 모델을 HuggingFace 형식으로 내보내는 것입니다. 내보내는 방법은 다음과 같습니다:

python EasyLM/EasyLM/models/llama/convert_easylm_to_hf.py \
--load_checkpoint='params::/path/to/output/model/streaming_params' \
--tokenizer_path='/path/to/tokenizer' \
--model_size='7b' \
--output_dir='/path/to/converted/model'

결론

2023년은 오픈 소스 제너레이티브 AI 모델에 있어 큰 이정표가 될 것입니다. 이 글을 쓰는 현재, 누구나 LLaMA, OpenLLaMA, XGen, Orca, Falcon과 같은 훌륭한 모델을 사용할 수 있습니다.

이러한 모델을 미세 조정하는 것은 사용 사례에 맞게 맞춤화된 최첨단 결과를 얻을 수 있는 가장 좋은 방법이며, ChatGPT(GPT-3.5), GPT-4, Claude...와 같은 최고의 독점 AI 모델을 훨씬 능가할 수 있습니다.

이 가이드에서는 LLaMA, OpenLLaMA, XGen을 미세 조정하는 방법을 보여드렸습니다. 궁금한 점이 있으시면 언제든지 문의해 주시고, 기술적 복잡성 없이 고급 생성 AI 모델을 쉽게 미세 조정하고 배포하고 싶으시다면 언제든지 문의해 주세요, have a look at the NLP Cloud dedicated documentation!

Mark
NLP 클라우드의 머신 러닝 엔지니어