!pip install -q transformers==4.40.0 accelerate gradio
import os
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
model_id = 'beomi/Llama-3-Open-Ko-8B-Instruct-preview'
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map="auto",
)
model.eval()
PROMPT = '''친절한 챗봇으로서 상대방의 요청에 최대한 친절하게 답하자.모든 대답은 한국어로 대답해줘.'''
instruction = "Python에서 입력된 두개의 문자열을 합쳐서 출력 하는 함수(def)를 만들어줘"
messages = [
{"role": "system", "content": f"{PROMPT}"},
{"role": "user", "content": f"{instruction}"}
"system" 역할:
-> 시스템 메시지는 모델의 전체적인 행동 지침, 컨텍스트, 스타일 등을 제시.
-> 예를 들어 PROMPT 라는 시스템 메시지에는 모델이 대화를 진행할 때 따라야 할 규칙이나 제약사항, 그 리고 전체적인 대화의 주제를 제시
-> 이후 사용자와의 대화 도중에도 모델은 시스템 메시지에 제시된 가이드라인을 참고하여 응답을 생성
-> 꼭 그 역할을 지키는것은 아님
"user" 역할:
-> 사용자 메시지는 모델이 실제로 응답을 생성해야 하는 지시
-> 사용자가 명령이나 질문을 던지는 형태로, 이를 통해 모델은 현재 대화 차례에서 무엇에 답해야 하는지 를 파악
messages를 모델이 이해할 수 있는 입력 형식으로 변환
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=True,
temperature=1,
top_p=0.9,
)
-> input_ids 로부터 최대 512 토큰의 새로운 텍스트를 샘플링 방식으로 생성
-> eos_token_id 로 지정한 terminators 토큰을 만나면 출력을 멈추며,
-> temperature=1 과 top_p=0.9 는 생성 시의 랜덤성과 다양성을 조절
--> 1보다 작으면 모델이 더 보수적으로, 높은 확률의 토큰을 선호하게 되고,
--> 1보다 크면 더 다양한(확률이 낮은) 토큰도 선택하는 경향이 커짐
--> top_p=0.9 는 누클리어스 샘플링(Nucleus Sampling) 기법을 적용하는 파라미터
--> 모델이 다음 단어를 선택할 때 전체 확률 분포 중 상위 90%의 누적 확률을 차지하는 토큰들만 후보로 삼 도록 제한
--> 아주 낮은 확률을 가진 토큰들은 거의 선택되지 않아 출력 품질을 유지
--> 단순히 가장 확률이 높은 단어만 택하는 것보다 더 다양한 응답을 생성
from pprint import pprint
response = outputs[0][input_ids.shape[-1]:]
pprint(tokenizer.decode(response, skip_special_tokens=True))

Gradio는 머신러닝(특히 딥러닝) 모델을 웹 인터페이스 형태로 빠르고 손쉽게 공유하고 시연할 수 있도록 도와 주는 Python 라이브러리
복잡한 웹 서버나 프론트엔드 구현 없이도 간단한 함수 호출만으로 웹 브라우저에서 모델의 입력/출력 인터페이 스(텍스트 박스, 이미지 업로드, 음성 녹음 등)를 생성
메시지를 만드는 함수
def build_messages(PROMPT, chat_history, input_text):
messages = [{"role": "system", "content": f"{PROMPT}"}]
for message in chat_history:
user_msg, assistant_msg = message
messages.append({"role": "user", "content": user_msg})
messages.append({"role": "assistant", "content": assistant_msg})
messages.append({"role": "user", "content": input_text})
return messages
def get_input_ids(tokenizer, model, messages):
input_ids = tokenizer.apply_chat_template(
messages,
add_generation_prompt=True,
return_tensors="pt"
).to(model.device)
return input_ids
def get_terminators(tokenizer):
terminators = [
tokenizer.eos_token_id,
tokenizer.convert_tokens_to_ids("<|eot_id|>")
]
return terminators
def generate_outputs(model, input_ids, terminators):
outputs = model.generate(
input_ids,
max_new_tokens=512,
eos_token_id=terminators,
do_sample=True,
temperature=1,
top_p=0.9,
)
return outputs
def decode_response(tokenizer, outputs, input_ids):
response_ids = outputs[0][input_ids.shape[-1]:]
response = tokenizer.decode(response_ids, skip_special_tokens=True)
return response
def generate_response(input_text, chat_history):
messages = build_messages(PROMPT, chat_history, input_text)
input_ids = get_input_ids(tokenizer, model, messages)
terminators = get_terminators(tokenizer)
outputs = generate_outputs(model, input_ids, terminators)
response = decode_response(tokenizer, outputs, input_ids)
chat_history.append((input_text, response))
return "", chat_history
import gradio as gr
with gr.Blocks() as demo:
chatbot = gr.Chatbot(height=600)
msg = gr.Textbox()
clear = gr.Button("Clear")
msg.submit(generate_response, [msg, chatbot], [msg, chatbot])
clear.click(lambda: None, None, chatbot, queue=False)
demo.launch()
이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다