[논문 리뷰 및 활용] Chat-Vector

nebchi·2024년 6월 17일
0

LLM

목록 보기
11/11

Chat Vector

  • 채팅 벡터를 활용하여 LLM의 기존 지식과 행동을 효율적으로 수행하는 방법을 소개합니다.
  • 위 작업을 수행하기 위해 meta의 llama-2 base 모델과 Instruction 모델 그리고, 특정 언어로 사전학습된 모델 3가지가 필요합니다.
  • 여기서는 한국어로 사전학습된 모델을 사용하였습니다.

1. Instroduction

  • LLM은 사전학습, SFT, RLHF 3가지 기본 단계가 있습니다.
  • 사전학습은 일반화된 지식을 얻기 위해 목표로 하는 반면 SFT는 모델을 더 잘 정렬하기 위해 명령 조정에 중점을 둡니다. 반면에 RLHF는 사람의 피드백을 통해 잘못된 정보나 유해한 표현을 해결함으로써, 모델의 환각현상을 효과적으로 줄여줍니다.
  • 하지만 위 3 단계는 기술적 문제로 복잡하고, RLHF에서 보상 모델과 추론 모델을 동시에 포함하는 여러 LM을 교육하는 절차는 메모리 및 계산 요구사항을 크게 증폭시킵니다.
  • 그래서 우리는 기존 LLM 교육 패러다임을 재구성하는 방식을 제안합니다.
  • LLaMA-2-chat 가중치에서 LLaMA-2의 사전 훈련된 가중치를 빼서, Chat-Vector를 생성하고, 비영어권 언어로 사전학습된 모델에 Chat-Vector를 도입함으로써, 메모리 및 계산 요구사항을 크게 줄인 채, Chat 모델을 개발할 수 있었습니다.

Chat Vector

  • LLM의 학습된 가중치 매개변수를 더하여 사전 학습된 모델에 상호작용 능력을 부여하는 기술
  • 영어 사전학습 모델과 한국어 사전학습 모델, 그리고 지시튜닝 모델 3개를 이용
  • 영어 채팅 모델의 가중치에서 기본 모델의 가중치를 뺀 것은 채팅 형식으로 상호작용 할 수 있는 능력을 나타내고, 이를 다른 모델의 가중치에 더해지면 채팅능력이 부여됨

2. 한국어 사전학습 모델에 Chat Vector 활용하기

# 영어 사전학습 모델 및 지시튜닝 모델 로드하기
from transformers import AutoModelForCausalLM
import torch

base_model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Meta-Llama-3-8B",
    torch_dtype=torch.bfloat16,
    device_map='auto',
)

inst_model = AutoModelForCausalLM.from_pretrained(
     "meta-llama/Meta-Llama-3-8B-Instruct",
    torch_dtype=torch.bfloat16,
    device_map='auto',
)

# 한국어 사전학습 모델 로드하기
cp_model = AutoModelForCausalLM.from_pretrained(
    "beomi/Llama-3-KoEn-8B",
    torch_dtype=torch.bfloat16,
    device_map='auto',
)
# 사전학습 시, 모델의 토크나이저를 확장하면 입력과 출력 임베딩의 크기가 달라져서 계산에서 제외함.
skip_layers = ["model.embed_tokens.weight", "lm_head.weight"]

# 모델 layers에서 base 모델과 chat 모델의 가중치를 뺀 값으로 chat vector를 생성하고, 이를 한국어로 사전학습된 모델에 추가함. 
for k, v in cp_model.state_dict().items():
    if (k in skip_layers) or ("layernorm" in k):
        continue
    chat_vector = inst_model.state_dict()[k] - base_model.state_dict()[k]
    new_v = v + chat_vector.to(v.device)
    v.copy_(new_v)

cp_model.save_pretrained("저장할 모델이름")

3. 기존 사전학습 모델 결과

# 기존 base 모델 결과
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline, TextStreamer
import torch

tokenizer = AutoTokenizer.from_pretrained(
    "beomi/Llama-3-KoEn-8B",
)

model = AutoModelForCausalLM.from_pretrained(
    "beomi/Llama-3-KoEn-8B",
    torch_dtype=torch.bfloat16,
    device_map='auto',
    cache_dir = '/data',
)
streamer = TextStreamer(tokenizer)

messages = [
    {"role": "system", "content": "당신은 인공지능 어시스턴트입니다. 묻는 말에 친절하고 정확하게 답변하세요."},
    {"role": "user", "content": "대한민국의 수도에 대해 알려줘"},
]

input_ids = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt"
).to(model.device)

terminators = [
    tokenizer.eos_token_id,
    tokenizer.convert_tokens_to_ids("<|eot_id|>")
]

outputs = model.generate(
    input_ids,
    max_new_tokens=512,
    eos_token_id=terminators,
    do_sample=False,
    repetition_penalty=1.05,
    streamer = streamer
)
response = outputs[0][input_ids.shape[-1]:]
print(tokenizer.decode(response, skip_special_tokens=True))

# 출력 결과
<|begin_of_text|><|start_header_id|>system<|end_header_id|>

당신은 인공지능 어시스턴트입니다. 묻는 말에 친절하고 정확하게 답변하세요.<|eot_id|><|start_header_id|>user<|end_header_id|>

대한민국의 수도에 대해 알려줘<|eot_id|><|start_header_id|>assistant<|end_header_id|>

서울특별시입니다.지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?
  • 위 결과를 보면, 서울특별시라고 말한 뒤, 중복된 단어를 계속해서 생성하는 문제가 발생

4. Chat-Vector 모델 결과

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline, TextStreamer
import torch

tokenizer = AutoTokenizer.from_pretrained(
    "beomi/Llama-3-KoEn-8B",
)

model = AutoModelForCausalLM.from_pretrained(
    "./chat_model",
    torch_dtype=torch.bfloat16,
    device_map='auto',
)
streamer = TextStreamer(tokenizer)

messages = [
    {"role": "system", "content": "당신은 인공지능 어시스턴트입니다. 묻는 말에 친절하고 정확하게 답변하세요."},
    {"role": "user", "content": "대한민국의 수도에 대해 알려줘"},
]

input_ids = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt"
).to(model.device)

terminators = [
    tokenizer.eos_token_id,
    tokenizer.convert_tokens_to_ids("<|eot_id|>")
]

outputs = model.generate(
    input_ids,
    max_new_tokens=512,
    eos_token_id=terminators,
    do_sample=False,
    repetition_penalty=1.05,
    streamer = streamer
)
response = outputs[0][input_ids.shape[-1]:]
print(tokenizer.decode(response, skip_special_tokens=True))

# 출력 결과
<|begin_of_text|><|start_header_id|>system<|end_header_id|>

당신은 인공지능 어시스턴트입니다. 묻는 말에 친절하고 정확하게 답변하세요.<|eot_id|><|start_header_id|>user<|end_header_id|>

대한민국의 수도에 대해 알려줘<|eot_id|><|start_header_id|>assistant<|end_header_id|>

대한민국의 수도는 서울특별시입니다. 서울특별시에는 청와대, 국회의사당, 대법원 등 대한민국의 주요 정부기관이 위치해 있습니다. 또한 서울시는 대한민국의 경제, 문화, 교육, 교통의 중심지로써 대한민국의 수도이자 대표 도시입니다.제가 도움이 되었길 바랍니다. 더 궁금한 점이 있으시면 언제든지 물어보세요!​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  • Chat Vector를 통해 기존 LLaMA3-instruct 모델의 가중치를 한국어 사전학습 모델에 병합하여, 채팅 형식으로 대답이 가능함을 확인할 수 있다.

참고 문헌

1) Chat Vector
https://arxiv.org/abs/2310.04799

profile
NLP Developer

0개의 댓글