Chat Vector
- LLM의 학습된 가중치 매개변수를 더하여 사전 학습된 모델에 상호작용 능력을 부여하는 기술
- 영어 사전학습 모델과 한국어 사전학습 모델, 그리고 지시튜닝 모델 3개를 이용
- 영어 채팅 모델의 가중치에서 기본 모델의 가중치를 뺀 것은 채팅 형식으로 상호작용 할 수 있는 능력을 나타내고, 이를 다른 모델의 가중치에 더해지면 채팅능력이 부여됨
# 영어 사전학습 모델 및 지시튜닝 모델 로드하기
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("저장할 모델이름")
# 기존 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|>
서울특별시입니다.지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?지도를 보여드릴까요?
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|>
대한민국의 수도는 서울특별시입니다. 서울특별시에는 청와대, 국회의사당, 대법원 등 대한민국의 주요 정부기관이 위치해 있습니다. 또한 서울시는 대한민국의 경제, 문화, 교육, 교통의 중심지로써 대한민국의 수도이자 대표 도시입니다.제가 도움이 되었길 바랍니다. 더 궁금한 점이 있으시면 언제든지 물어보세요!
1) Chat Vector
https://arxiv.org/abs/2310.04799