예전에 조금 끄적거렸던... (흔적은 없지만) 허깅페이스가 떠올라 랭체인과 같이 써보면 어떨까 싶어서 급하게(?) 하나 만들어 봤다.
https://huggingface.co/settings/tokens 에 접속하면 우측에 +Create New Token 버튼이 있는데 클릭하여 발급한다.
HUGGINGFACE_API_KEY=hf_pxuVmGYkaBzfKsV.............
중복 존재 가능...
pip install langchain-huggingface transformers huggingface-hub python-dotenv torch
from langchain_community.chat_models import ChatHuggingFace
from langchain_community.llms import HuggingFaceHub
from huggingface_hub import login
from transformers import AutoTokenizer
import os
# 4B 크기의 한국어 모델로 변경
llm_model_name = "google/gemma-2-2b-it"
# LLM(대형 언어 모델)을 생성하는 함수
def getLlmHuggingface():
# HuggingFace Hub에 로그인
huggingface_token = os.getenv("HUGGINGFACE_API_KEY")
if not huggingface_token:
raise ValueError("HUGGINGFACE_API_KEY not found in environment variables")
login(token=huggingface_token)
# 토크나이저 로드 및 chat template 설정
tokenizer = AutoTokenizer.from_pretrained(llm_model_name)
# tokenizer.chat_template = "{% for message in messages %}{% if message['role'] == 'user' %}{{ '### Human: ' + message['content'] + '\n' }}{% elif message['role'] == 'assistant' %}{{ '### Assistant: ' + message['content'] + '\n' }}{% endif %}{% endfor %}"
# HuggingFaceHub LLM 초기화
llm = HuggingFaceHub(
repo_id=llm_model_name,
huggingfacehub_api_token=huggingface_token,
model_kwargs={
"temperature": 0.7,
"max_length": 512,
"do_sample": True
}
)
# ChatHuggingFace 모델 초기화
chat_llm = ChatHuggingFace(
llm=llm,
tokenizer=tokenizer,
huggingfacehub_api_token=huggingface_token
)
return chat_llm # 생성된 LLM 반환
from modules.llm.llm_huggingface_hub import getLlmHuggingface
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser
llm = getLlmHuggingface()
prompt = ChatPromptTemplate.from_template("안녕하세요, 제 이름은 {name}이고, 나이는 {age}살입니다.")
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"name": "exoluse", "age": 10})
print(result)
먼저 허깅페이스 허브에서 다운로드를 받은 후
이와 같은 결과물을 내어준다.
from transformers import AutoTokenizer, AutoModelForCausalLM
import os
from dotenv import load_dotenv
load_dotenv()
token = os.getenv("HUGGINGFACE_API_KEY")
tokenizer = AutoTokenizer.from_pretrained("EleutherAI/polyglot-ko-1.3b", token=token, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("EleutherAI/polyglot-ko-1.3b", token=token, trust_remote_code=True)
# 토크나이저에게 "패딩 토큰은 종료 토큰과 동일하다" 라고 알려줌
# 짧은 입력을 채워주는 용도로 사용되는 특수 토큰이 바로 pad_token
# 일반적으로 GPT2, GPT-J 는 pad_token 이 없음.
tokenizer.pad_token = tokenizer.eos_token
# 모델 설정에 pad_token_id가 없을 수 있기 때문에 명시적으로 설정
# 모델의 내부 설정(config)에 "이 정수값은 pad(빈칸)으로 처리해" 라고 지정
model.config.pad_token_id = tokenizer.eos_token_id
# generate()는 토큰을 만들다가 eos_token_id가 생성되면 중단하게 하는 설정.
# "이 토큰이 나오면 텍스트 생성을 멈춰라"
model.config.eos_token_id = tokenizer.eos_token_id
# input_ids, token_type_ids, attention_mask 가 있음
# tokenizer는 일반적으로 BERT 계열 기준으로 설계된 기능을 포함하고 있음.
input = tokenizer("안녕하세요? 인천은 좋은 곳인가요?", return_tensors="pt")
# casualLM 모델은 token_type_ids 없음
# 모델에는 token_type_ids 없는 경우가 있음.
input.pop("token_type_ids", None) # 있으면 제거
# 딕셔너리를 키워드 인자들로 분해해서 generate()에 전달
# input_ids, attention_mask 가 있음
outputs = model.generate(
**input,
max_new_tokens=500,
do_sample=True,
temperature=0.7,
top_p=0.9
)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
다음번에는 임베딩 모델을 허깅페이스에서 끌어다가 postgresql 에 데이터 넣고 질문해보는 것을 해봐야겠다...