Model Serialization

모델 직렬화 및 저장/로딩 방법

LangChain 모델의 직렬화(Serialization) 개념과 방법을 다룬다. 모델을 저장 가능한 형식으로 변환하여 재사용, 배포, 버전 관리를 용이하게 하는 방법을 설명한다.

AI
RAG
LangChain
저자

Kwangmin Kim

공개

2025년 02월 03일

0.1 직렬화(Serialization) 란?

  1. 정의:
    • 모델을 저장 가능한 형식으로 변환하는 과정
  2. 목적:
    • 모델 재사용 (재훈련 없이)
    • 모델 배포 및 공유 용이
    • 계산 리소스 절약
  3. 장점:
    • 빠른 모델 로딩
    • 버전 관리 가능
    • 다양한 환경에서 사용 가능

모델 직렬화는 AI 개발 및 배포 과정에서 중요한 단계로, 효율적인 모델 관리와 재사용을 가능하게 합니다.

is_lc_serializable 클래스 메서드로 실행하여 LangChain 클래스가 직렬화 가능한지 확인할 수 있습니다.

# API KEY를 환경변수로 관리하기 위한 설정 파일
from dotenv import load_dotenv

# API KEY 정보로드
load_dotenv()
# LangSmith 추적을 설정합니다. https://smith.langchain.com
# !pip install langchain-teddynote
from langchain_teddynote import logging

# 프로젝트 이름을 입력합니다.
logging.langsmith("CH04-Models")
import os
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate

# 프롬프트 템플릿을 사용하여 질문을 생성합니다.
prompt = PromptTemplate.from_template("{fruit}의 색상이 무엇입니까?")

클래스(class) 에 대하여 직렬화 가능 여부를 확인합니다.

# 직렬화가 가능한지 체크합니다.
print(f"ChatOpenAI: {ChatOpenAI.is_lc_serializable()}")

llm 객체에 대하여 직렬화 가능 여부를 확인합니다.

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

# 직렬화가 가능한지 체크합니다.
print(f"ChatOpenAI: {llm.is_lc_serializable()}")
# 체인을 생성합니다.
chain = prompt | llm

# 직렬화가 가능한지 체크합니다.
chain.is_lc_serializable()

1 체인(Chain) 직렬화(dumps, dumpd)

1.1 개요

체인 직렬화는 직렬화 가능한 모든 객체를 딕셔너리 또는 JSON 문자열로 변환하는 과정을 의미합니다.

1.2 직렬화 방법

객체의 속성 및 데이터를 키-값 쌍으로 저장하여 딕셔너리 형태로 변환합니다.

이러한 직렬화 방식은 객체를 쉽게 저장하고 전송할 수 있게 하며, 다양한 환경에서 객체를 재구성할 수 있도록 합니다.

참고 - dumps: 객체를 JSON 문자열로 직렬화 - dumpd: 객체를 딕셔너리로 직렬화

from langchain_core.load import dumpd, dumps

dumpd_chain = dumpd(chain)
dumpd_chain
# 직렬화된 체인의 타입을 확인합니다.
type(dumpd_chain)

이번에는 dumps 함수를 사용하여 직렬화된 체인을 확인해보겠습니다.

# dumps 함수를 사용하여 직렬화된 체인을 확인합니다.
dumps_chain = dumps(chain)
dumps_chain
# 직렬화된 체인의 타입을 확인합니다.
type(dumps_chain)

2 Pickle 파일

2.1 개요

Pickle 파일은 Python 객체를 바이너리 형태로 직렬화하는 포맷입니다.

2.2 특징

  1. 형식:
    • Python 객체를 바이너리 형태로 직렬화하는 포맷
  2. 특징:
    • Python 전용 (다른 언어와 호환 불가)
    • 대부분의 Python 데이터 타입 지원 (리스트, 딕셔너리, 클래스 등)
    • 객체의 상태와 구조를 그대로 보존
  3. 장점:
    • 효율적인 저장 및 전송
    • 복잡한 객체 구조 유지
    • 빠른 직렬화/역직렬화 속도
  4. 단점:
    • 보안 위험 (신뢰할 수 없는 데이터 역직렬화 시 주의 필요)
    • 사람이 읽을 수 없는 바이너리 형식

2.3 주요 용도

  1. 객체 캐싱
  2. 머신러닝 모델 저장
  3. 프로그램 상태 저장 및 복원

2.4 사용법

  • pickle.dump(): 객체를 파일에 저장
  • pickle.load(): 파일에서 객체 로드

pickle 파일로 저장합니다.

import pickle

# fuit_chain.pkl 파일로 직렬화된 체인을 저장합니다.
with open("fruit_chain.pkl", "wb") as f:
    pickle.dump(dumpd_chain, f)

JSON 형식으로 마찬가지로 저장할 수 있습니다.

import json

with open("fruit_chain.json", "w") as fp:
    json.dump(dumpd_chain, fp)

3 load: 저장한 모델 불러오기

먼저, 이전에 저장한 pickle 형식의 파일을 로드합니다.

import pickle

# pickle 파일을 로드합니다.
with open("fruit_chain.pkl", "rb") as f:
    loaded_chain = pickle.load(f)

로드한 json 파일을 load 메서드를 사용하여 로드합니다.

from langchain_core.load import load

# 체인을 로드합니다.
chain_from_file = load(loaded_chain)

# 체인을 실행합니다.
print(chain_from_file.invoke({"fruit": "사과"}))
from langchain_core.load import load, loads

load_chain = load(
    loaded_chain, secrets_map={"OPENAI_API_KEY": os.environ["OPENAI_API_KEY"]}
)

# 불러온 체인이 정상 동작하는지 확인합니다.
load_chain.invoke({"fruit": "사과"})
with open("fruit_chain.json", "r") as fp:
    loaded_from_json_chain = json.load(fp)
    loads_chain = load(loaded_from_json_chain)
# 불러온 체인이 정상 동작하는지 확인합니다.
loads_chain.invoke({"fruit": "사과"})

Subscribe

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