안녕 모두들!
이전 게시물 중 하나에서 미세 조정과 그것이 중요한 이유에 대해 이야기했습니다. 이 게시물에서는 Instruction Finetuning이라는 특정 종류의 미세 조정을 살펴보겠습니다.
gpt-3과 같은 사전 훈련된 기본 모델은 방대한 양의 데이터에 대해 훈련됩니다. gpt-3의 경우 인터넷에 있는 모든 데이터입니다. 글쎄요, 우리는 확실히 알지 못하지만 이러한 모델의 대부분은 상당한 수동 정리 및 포맷 후 인터넷 규모 데이터에 대해 훈련되었습니다. 훈련을 받으면서 기반 모델은 다음 토큰을 예측하는 방법을 배우고 토큰 예측에 능숙해집니다. 그러나 순수한 토큰 예측은 생각만큼 유용하지 않습니다. 사전 훈련된 기본 모델에 " 멕시코의 수도는 무엇입니까?" 라고 묻는다면 ”라고 대답하는 것은 아니지만, “ 콜롬비아의 수도는 무엇입니까 ?”로 입력 문장을 완성할 수도 있습니다. 따라서 gpt-3과 같은 모델이 토큰 예측에 강력하더라도 챗봇이나 부조종사로는 작동하지 않습니다. 그렇다면 사전 훈련된 모델을 chat-gpt와 같은 유용한 챗봇으로 어떻게 변환합니까? 대답은 미세 조정이며, 주로 " 명령 미세 조정 "이라고 하는 특정 유형의 미세 조정입니다.
"명령 따르기"라고도 하는 명령 미세 조정은 사전 훈련된 기본 모델이 채팅 봇처럼 동작하도록 가르치는 프로세스입니다.
명령어 미세 조정에는 질문과 답변 형식의 데이터 세트가 필요합니다. 공개 데이터 세트나 Q&A 형식의 회사 데이터 세트를 사용할 수 있습니다. 데이터 세트가 Q&A 형식이 아닌 경우 Alpaca와 같은 다른 기술을 사용하거나 다른 LLM의 사용자 정의 프롬프트를 사용하여 데이터를 Q&A로 변환할 수 있습니다. 명령 미세 조정은 미세 조정에 사용하는 데이터에 대한 질문에 답하는 새로운 동작을 모델에 제공할 뿐만 아니라 이 새로운 동작은 모델이 이미 가지고 있는 기존 지식에 적용 가능하므로 미세 조정을 강력한 기술로 만듭니다.
Lamini는 개발자가 호스팅, 교육 및 기타 복잡한 측면의 복잡성을 추상화하여 쉬운 방법으로 언어 모델을 처리할 수 있도록 하는 AI 회사입니다. 여기에서 전체 기능을 확인하세요. Lamini를 사용하여 Eleuther AI 에서 만든 오픈 소스 모델인 pythia 라는 작은 언어 모델을 훈련하고 Alpaca라는 회사 데이터 세트를 사용하여 이에 대한 명령 미세 조정을 수행합니다.
이 단계에서는 필요한 모듈을 초기화하고 알파카 훈련 데이터 세트도 살펴보겠습니다. 코드는 다음과 같습니다.
import itertools import jsonlines from datasets import load_dataset from pprint import pprint from llama import BasicModelRunner from transformers import AutoTokenizer, AutoModelForCausalLM from transformers import AutoModelForSeq2SeqLM, AutoTokenizer ## we are using alpaca data set, which is an open source fine tuning data set instruction_tuned_dataset = load_dataset("tatsu-lab/alpaca", split="train", streaming=True) m = 5 print("Instruction-tuned dataset:") top_m = list(itertools.islice(instruction_tuned_dataset, m)) for j in top_m: print(j)
이것이 명령어 튜닝 데이터 세트의 모습입니다. 질문과 답변 형태의 데이터가 포함되어 있습니다.
이 단계에서는 알파카 세트에서 데이터를 가져와 아래 표시된 프롬프트에 입력합니다.
prompt_template_with_input = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request. ### Instruction: {instruction} ### Input: {input} ### Response:""" prompt_template_without_input = """Below is an instruction that describes a task. Write a response that appropriately completes the request. ### Instruction: {instruction} ### Response:""" ## hydrate prompts - meaning add data to the above prompts processed_data = [] for j in top_m: if not j["input"]: processed_prompt = prompt_template_without_input.format(instruction=j["instruction"]) else: processed_prompt = prompt_template_with_input.format(instruction=j["instruction"], input=j["input"]) processed_data.append({"input": processed_prompt, "output": j["output"]})
이 작업을 수행하면 데이터 세트는 다음과 같이 표시됩니다.
우리는 기본적으로 원시 Q&A 데이터를 가져와 질문을 받았을 때 해당 질문에 대한 응답이 어떻게 보여야 하는지 LLM에 적합한 형식으로 변환합니다. 이 작업을 반복적으로 수행하고 jsonl 파일에 저장합니다.
with jsonlines.open(f'alpaca_processed.jsonl', 'w') as writer: writer.write_all(processed_data)
1, 2단계에서는 원시 데이터를 로드하고 이를 수화하여 jsonl 형식으로 저장했습니다. 그러나 Lamini는 이 수화된 데이터를 사용할 준비가 되어 있으므로 기술적으로 1단계와 2단계는 필요하지 않습니다. 그러나 명령 미세 조정이 어떻게 작동하는지 이해하기 위해서는 보여주는 것이 필요했습니다. 먼저 미세 조정되지 않은 버전의 Pythia 모델이 간단한 질문에 어떻게 응답하는지 살펴보겠습니다.
tokenizer = AutoTokenizer.from_pretrained("EleutherAI/pythia-70m") #70M parameter model that is not instruction tuned. model = AutoModelForCausalLM.from_pretrained("EleutherAI/pythia-70m") def inference(text, model, tokenizer, max_input_tokens=1000, max_output_tokens=100): # Tokenize input_ids = tokenizer.encode( text, return_tensors="pt", truncation=True, max_length=max_input_tokens ) # Generate device = model.device generated_tokens_with_prompt = model.generate( input_ids=input_ids.to(device), max_length=max_output_tokens ) # Decode generated_text_with_prompt = tokenizer.batch_decode(generated_tokens_with_prompt, skip_special_tokens=True) # Strip the prompt generated_text_answer = generated_text_with_prompt[0][len(text):] return generated_text_answer ## the 70M model doesnt have any company specific data, we will use the alpace data set from hosted on lamini and fine tune this model # load alpaca dataset finetuning_dataset_path = "lamini/lamini_docs" finetuning_dataset = load_dataset(finetuning_dataset_path) #print(finetuning_dataset) test_sample = finetuning_dataset["test"][0] print(test_sample) print("untrained output sample") print(inference(test_sample["question"], model, tokenizer))
이것이 내가 얻은 결과입니다. 출력이 도움이 되지 않고 모델이 토큰 완성을 시도하지만 실제 답변을 제공하지 않는다는 것을 알 수 있습니다.
이전 단계에서 본 Q&A 데이터를 사용하여 미세 조정을 지시하면 동일한 모델이 채팅 봇처럼 작동하기 시작하고 미세한 데이터뿐만 아니라 모델이 이미 생성한 데이터에 대한 질문에 더 정확한 답변을 제공합니다. 꺼져 있습니다. 마치 아이가 처음 언어를 배울 때, 언어 훈련을 통해 배운 새로운 것과 이미 가지고 있는 감정을 표현할 수 있게 되는 것과 같습니다. 사전 학습된 모델 버전과 마찬가지로 지침 미세 조정 모델도 Lamini에서 호스팅되며 아래와 같은 명령을 사용하여 추론할 수 있습니다. (예, Lamini는 훌륭합니다!)
## finetuned output instruction_model = AutoModelForCausalLM.from_pretrained("lamini/lamini_docs_finetuned") print("instruction finetuned output") print(inference(test_sample["question"], instruction_model, tokenizer))
출력은 다음과 같습니다. 이전 단계에서 본 횡설수설 대신 더 정확한 출력이 있다는 것을 알 수 있습니다.
이 게시물의 목표는 명령어 미세 조정 에 대한 소개와 기본 모델을 보다 유용한 버전으로 만드는 데 사용되는 방법을 제공하는 것입니다. 향후 게시물에서는 명령어 미세 조정을 수행하는 실제 프로세스에 대해 자세히 알아볼 것입니다.
AI 100일 중 13일차가 끝났습니다.
나는 대형 기술 분야에서 일어나는 모든 일 뒤에 숨어 있는 2차 통찰력에 대해 이야기하는 Above Average라는 뉴스레터를 작성합니다. 기술 분야에 종사하고 평범해지고 싶지 않다면 구독하세요 .
AI 100일에 대한 최신 업데이트를 보려면 Twitter , LinkedIn 에서 저를 팔로우하세요. 기술 분야에 종사하는 분이라면 여기에서 제 기술 전문가 커뮤니티에 가입하는 데 관심이 있으실 것입니다.
여기에도 나타납니다.