HuggingFace Pipelines

HuggingFace Transformers 파이프라인 활용

HuggingFace Model Hub의 120,000개 이상 모델을 로컬 파이프라인으로 실행하는 방법을 다룬다. PyTorch와 Transformers를 활용한 로컬 모델 실행 및 메모리 효율적인 추론 기법을 설명한다.

AI
RAG
LangChain
저자

Kwangmin Kim

공개

2025년 02월 08일

HuggingFacePipeline 클래스를 통해 Hugging Face 모델을 로컬에서 실행할 수 있습니다.

Hugging Face Model Hub는 온라인 플랫폼에서 120,000개 이상의 모델, 20,000개의 데이터셋, 50,000개의 데모 앱(Spaces)을 호스팅하며, 모두 오픈 소스이고 공개적으로 사용 가능하여 사람들이 쉽게 협업하고 함께 ML을 구축할 수 있습니다.

이러한 모델은 LangChain에서 이 로컬 파이프라인 래퍼를 통해 호출하거나, HuggingFaceHub 클래스를 통해 호스팅된 추론 엔드포인트를 호출하여 사용할 수 있습니다. 호스팅된 파이프라인에 대한 자세한 내용은 HuggingFaceHub 노트북을 참조하세요.

사용하기 위해서는 PyTorch와 함께 Python 패키지 transformers가 설치되어 있어야 합니다.

또한, 보다 메모리 효율적인 attention 구현을 위해 xformer를 설치할 수도 있습니다.

# 설치
# !pip install -qU transformers

모델을 다운로드 받을 경로를 설정

# 허깅페이스 모델/토크나이저를 다운로드 받을 경로
import os

# ./cache/ 경로에 다운로드 받도록 설정
os.environ["HF_HOME"] = "./cache/"
# LangSmith 추적을 설정합니다. https://smith.langchain.com
# !pip install langchain-teddynote
from langchain_teddynote import logging
from langchain_teddynote.messages import stream_response

# 프로젝트 이름을 입력합니다.
logging.langsmith("CH04-Models")

0.1 Model Loading

모델은 from_model_id 메서드를 사용하여 모델 매개변수를 지정함으로써 로드할 수 있습니다.

  • HuggingFacePipeline 클래스를 사용하여 Hugging Face의 사전 학습된 모델을 로드합니다.
  • from_model_id 메서드를 사용하여 beomi/llama-2-ko-7b 모델을 지정하고, 작업을 “text-generation”으로 설정합니다.
  • pipeline_kwargs 매개변수를 사용하여 생성할 최대 토큰 수를 10으로 제한합니다.
  • 로드된 모델은 hf 변수에 할당되며, 이를 통해 텍스트 생성 작업을 수행할 수 있습니다.

사용한 모델: https://huggingface.co/beomi/llama-2-ko-7b

from langchain_huggingface import HuggingFacePipeline

# HuggingFace 모델을 다운로드 받습니다.
hf = HuggingFacePipeline.from_model_id(
    model_id="beomi/llama-2-ko-7b",  # 사용할 모델의 ID를 지정합니다.
    task="text-generation",  # 수행할 작업을 지정합니다. 여기서는 텍스트 생성입니다.
    # 파이프라인에 전달할 추가 인자를 설정합니다. 여기서는 생성할 최대 토큰 수를 10으로 제한합니다.
    pipeline_kwargs={"max_new_tokens": 512},
)

기존의 transformers pipeline을 직접 전달하여 로드할 수도 있습니다.

HuggingFacePipeline을 사용하여 텍스트 생성 모델을 구현합니다.

  • AutoTokenizerAutoModelForCausalLM을 사용하여 beomi/llama-2-ko-7b 모델과 토크나이저를 로드합니다.
  • pipeline 함수를 사용하여 “text-generation” 파이프라인을 생성하고, 모델과 토크나이저를 설정합니다. 최대 생성 토큰 수는 10으로 제한합니다.
  • HuggingFacePipeline 클래스를 사용하여 hf 객체를 생성하고, 생성된 파이프라인을 전달합니다.

이렇게 생성된 hf 객체를 사용하여 주어진 프롬프트에 대한 텍스트 생성을 수행할 수 있습니다.

from langchain_huggingface import HuggingFacePipeline
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline

# huggingface repository에 등록된 모델 ID를 지정합니다.
model_id = "microsoft/Phi-3-mini-4k-instruct"

# 토크나이저를 로드합니다.
tokenizer = AutoTokenizer.from_pretrained(model_id)

# 지정된 모델을 로드합니다.
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    # load_in_4bit=True, # bitsandbytes 설치되어 있는 경우(linux)
    # attn_implementation="flash_attention_2", # ampere GPU 가 있는 경우
)

# 파이프라인을 생성합니다.
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512)

# HuggingFacePipeline 객체를 생성하고, 생성된 파이프라인을 전달합니다.
hf = HuggingFacePipeline(pipeline=pipe)

0.2 Gated Model 의 사용

Gated Model 은 HuggingFace 에서 라이센스 동의 하에 이용할 수 있는 모델입니다.

사전에 모델 페이지에 접속하여 동의하신 후, Hugging Face 토큰을 발급 받아야 합니다.

아래는 Gated 모델을 사용하기 위한 예제입니다. HuggingFace 에서 발급받은 토큰을 아래와 같이 지정해 주어야 합니다.

from langchain_huggingface import HuggingFacePipeline
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline

# huggingface repository에 등록된 모델 ID를 지정합니다.
model_id = "google/gemma-7b-it"

# 이곳에 발급 받은 Hugging Face 토큰을 입력합니다.
your_huggingface_token = "hf_............................"

# 토크나이저를 로드합니다.
tokenizer = AutoTokenizer.from_pretrained(model_id, token=your_huggingface_token)

# 지정된 모델을 로드합니다.
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    token=your_huggingface_token,
    # load_in_4bit=True, # bitsandbytes 설치되어 있는 경우(linux)
    # attn_implementation="flash_attention_2", # ampere GPU 가 있는 경우
)

# 파이프라인을 생성합니다.
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512)

# HuggingFacePipeline 객체를 생성하고, 생성된 파이프라인을 전달합니다.
hf_llm = HuggingFacePipeline(pipeline=pipe)

실행 및 결과 확인

for token in hf_llm.stream("대한민국의 수도는 어디야?"):
    print(token, end="", flush=True)

0.3 Create Chain

모델이 메모리에 로드되면 프롬프트와 함께 구성하여 체인을 형성할 수 있습니다.

  • PromptTemplate 클래스를 사용하여 질문과 답변 형식을 정의하는 프롬프트 템플릿을 생성합니다.
  • prompt 객체와 hf 객체를 파이프라인으로 연결하여 chain 객체를 생성합니다.
  • chain.invoke() 메서드를 호출하여 주어진 질문에 대한 답변을 생성하고 출력합니다.
from huggingface_hub import login

login()
from langchain_huggingface import ChatHuggingFace

llm = ChatHuggingFace(llm=hf)
from langchain.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

template = """<|system|>You are a helpful assistant.<|end|>
<|user|>{question}<|end|>
<|assistant|>"""  # 질문과 답변 형식을 정의하는 템플릿

prompt = PromptTemplate.from_template(template)  # 템플릿을 사용하여 프롬프트 객체 생성

# 프롬프트와 언어 모델을 연결하여 체인 생성
chain = prompt | llm | StrOutputParser()

question = "대한민국의 수도는 어디야?"  # 질문 정의

# print(
# chain.invoke({"question": question})
# )  # 체인을 호출하여 질문에 대한 답변 생성 및 출력

answer = chain.stream({"question": question})
stream_response(answer)

0.4 GPU Inference

GPU에서 실행할 때는 device=n 매개변수를 지정하여 모델을 특정 디바이스에 배치할 수 있습니다.

기본값은 -1로, CPU에서 추론을 수행합니다.

여러 개의 GPU가 있거나 모델이 단일 GPU에 비해 너무 큰 경우에는 device_map="auto"를 지정할 수 있습니다.

이 경우 Accelerate 라이브러리가 필요하며, 모델 가중치를 어떻게 로드할지 자동으로 결정하는 데 사용됩니다.

주의: devicedevice_map은 함께 지정해서는 안 되며, 예기치 않은 동작을 유발할 수 있습니다.

  • HuggingFacePipeline을 사용하여 gpt2 모델을 로드하고, device 매개변수를 0으로 설정하여 GPU에서 실행되도록 합니다.
  • pipeline_kwargs 매개변수를 사용하여 생성할 최대 토큰 수를 10으로 제한합니다.
  • promptgpu_llm을 파이프라인으로 연결하여 gpu_chain을 생성합니다.
  • gpu_chain.invoke() 메서드를 호출하여 주어진 질문에 대한 답변을 생성하고 출력합니다.
gpu_llm = HuggingFacePipeline.from_model_id(
    model_id="beomi/llama-2-ko-7b",  # 사용할 모델의 ID를 지정합니다.
    task="text-generation",  # 수행할 작업을 설정합니다. 여기서는 텍스트 생성입니다.
    # 사용할 GPU 디바이스 번호를 지정합니다. "auto"로 설정하면 accelerate 라이브러리를 사용합니다.
    device=0,
    # 파이프라인에 전달할 추가 인자를 설정합니다. 여기서는 생성할 최대 토큰 수를 10으로 제한합니다.
    pipeline_kwargs={"max_new_tokens": 64},
)

gpu_chain = prompt | gpu_llm  # prompt와 gpu_llm을 연결하여 gpu_chain을 생성합니다.

# 프롬프트와 언어 모델을 연결하여 체인 생성
gpu_chain = prompt | gpu_llm | StrOutputParser()

question = "대한민국의 수도는 어디야?"  # 질문 정의

# 체인을 호출하여 질문에 대한 답변 생성 및 출력
print(gpu_chain.invoke({"question": question}))

0.5 Batch GPU Inference

GPU 장치에서 실행하는 경우, 배치 모드로 GPU에서 추론을 실행할 수 있습니다.

  • HuggingFacePipeline을 사용하여 beomi/llama-2-ko-7b 모델을 로드하고, GPU에서 실행되도록 설정합니다.
  • gpu_llm을 생성할 때 batch_size를 2로 설정하고, temperature를 0으로, max_length를 64로 설정합니다.
  • promptgpu_llm을 파이프라인으로 연결하여 gpu_chain을 생성하고, 종료 토큰을 “”로 설정합니다.
  • gpu_chain.batch()를 사용하여 questions의 질문들에 대한 답변을 병렬로 생성합니다.
  • 생성된 답변을 반복문을 통해 출력합니다.
gpu_llm = HuggingFacePipeline.from_model_id(
    model_id="beomi/llama-2-ko-7b",  # 사용할 모델의 ID를 지정합니다.
    task="text-generation",  # 수행할 작업을 설정합니다.
    device=0,  # GPU 디바이스 번호를 지정합니다. -1은 CPU를 의미합니다.
    batch_size=2,  # 배치 크기s를 조정합니다. GPU 메모리와 모델 크기에 따라 적절히 설정합니다.
    model_kwargs={
        "temperature": 0,
        "max_length": 256,
    },  # 모델에 전달할 추가 인자를 설정합니다.
)

# 프롬프트와 언어 모델을 연결하여 체인을 생성합니다.
gpu_chain = prompt | gpu_llm.bind(stop=["\n\n"])

questions = []
for i in range(4):
    # 질문 리스트를 생성합니다.
    questions.append({"question": f"숫자 {i} 이 한글로 뭐에요?"})

answers = gpu_chain.batch(questions)  # 질문 리스트를 배치 처리하여 답변을 생성합니다.
for answer in answers:
    print(answer)  # 생성된 답변을 출력합니다.

Subscribe

Enjoy this blog? Get notified of new posts by email: