기존 소설 학습해서 새 소설 써주는 랭체인 프로그램

GoGoComputer·2024년 11월 12일
0

studyEct

목록 보기
7/10
post-thumbnail

📖 소설 쓰는 랭체인

아래는 LangChain을 사용하여 소설 데이터를 학습시키고, 유사한 스타일로 소설을 작성하는 고퀄리티 코드 예시입니다. 이 코드는 가상 환경(venv)을 사용하고, API 키는 .env 파일에서 가져오며, 모델 I/O, 데이터, 체인, 메모리, 에이전트를 모두 포함합니다.

LangChain은 대형 언어 모델(LLM)을 체인 형태로 연결하여 복잡한 작업을 수행할 수 있게 해주는 강력한 도구입니다. 이를 통해 소설 데이터를 기반으로 새로운 소설을 생성하는 시스템을 구축할 수 있습니다.

🛠️ 1. 가상 환경 설정 및 필수 패키지 설치

먼저, 프로젝트의 의존성을 격리하기 위해 가상 환경(venv)을 생성하고 필요한 패키지를 설치합니다.

python3 -m venv myenv
source myenv/bin/activate  # Windows의 경우: myenv\Scripts\activate
pip install openai langchain python-dotenv
  • python3 -m venv myenv: 새로운 가상 환경 myenv를 생성합니다.
  • source myenv/bin/activate: 가상 환경을 활성화합니다.
  • pip install: 필요한 패키지를 가상 환경에 설치합니다.

코드를 구현하기 위해 필요한 pip 패키지는 다음과 같습니다:

pip install langchain python-dotenv langchain-ollama
  • langchain: 여러 언어 모델을 체인 형태로 연결하는 라이브러리
  • python-dotenv: 환경 변수를 로드하기 위한 패키지
  • langchain-ollama: LangChain과 Ollama를 통합하여 Llama 모델을 로컬에서 활용할 수 있게 해주는 패키지

📚 필수 패키지 설명

  • openai: OpenAI의 API를 사용하여 GPT-3.5 등의 언어 모델에 접근할 수 있게 해줍니다.
  • langchain: 여러 언어 모델을 체인 형태로 연결하여 복잡한 작업을 수행할 수 있게 하는 라이브러리입니다.
  • python-dotenv: .env 파일에서 환경 변수를 로드할 수 있게 해줍니다.

🔑 2. .env 파일 설정

API 키와 같은 민감한 정보를 코드에 직접 작성하는 것은 보안상 위험합니다. 따라서 .env 파일을 사용하여 환경 변수를 설정하고 코드에서 이를 불러오는 것이 좋습니다.

OPENAI_API_KEY=your_openai_api_key
  • your_openai_api_key를 실제 OpenAI API 키로 교체하세요.
  • .env 파일은 프로젝트 루트 디렉토리에 위치해야 하며, 버전 관리 시스템(git 등)에 포함되지 않도록 .gitignore에 추가해야 합니다.

🧠 3. LangChain 코드 구현

이제 LangChain을 사용하여 소설 생성 시스템을 구축하는 코드를 작성하겠습니다.

import os
from langchain import OpenAI, PromptTemplate, LLMChain
from langchain.chains import SequentialChain
from langchain.memory import ConversationBufferMemory
from dotenv import load_dotenv

# .env 파일에서 API 키 로드
load_dotenv()
openai_api_key = os.getenv("OPENAI_API_KEY")

# 1. OpenAI 모델 초기화
llm = OpenAI(api_key=openai_api_key, model="gpt-3.5-turbo")

# 2. 프롬프트 템플릿 설정
prompt_template = """
당신은 {style} 스타일의 소설 작가입니다. 당신의 스타일은 문학적이며 창의적입니다.
다음 주제를 기반으로 소설의 첫 문장을 작성하세요:
{topic}
"""

# 3. 체인과 메모리 설정
memory = ConversationBufferMemory()

prompt_chain = PromptTemplate(
    template=prompt_template, input_variables=["style", "topic"]
)
llm_chain = LLMChain(llm=llm, prompt=prompt_chain, output_key="text")

sequential_chain = SequentialChain(
    chains=[llm_chain],
    input_variables=["style", "topic"],
    output_variables=["text"],
    memory=memory,
    verbose=True
)

# 4. 소설 생성 함수 정의
def generate_story(style: str, topic: str):
    result = sequential_chain({"style": style, "topic": topic})
    return result["text"]

# 5. 예제 실행
style = "고풍스러운 문체와 서정적 어휘"
topic = "사랑과 운명에 관한 이야기"

story = generate_story(style, topic)
print(story)

📌 코드 상세 설명

1. 모델 초기화

  • OpenAI 클래스를 사용하여 OpenAI의 GPT-3.5-turbo 모델을 초기화합니다.
  • api_key.env 파일에서 로드한 API 키를 사용합니다.
  • model 파라미터는 사용할 언어 모델의 이름을 지정합니다.

2. 프롬프트 템플릿 설정

  • PromptTemplate은 모델에게 전달할 프롬프트의 구조를 정의합니다.
  • {style}{topic}은 동적으로 입력받을 변수입니다.
  • 프롬프트는 모델이 특정 스타일과 주제에 맞는 소설의 첫 문장을 생성하도록 지시합니다.

3. 체인과 메모리 설정

  • ConversationBufferMemory는 이전 대화 내용을 저장하여 컨텍스트를 유지합니다.
  • LLMChain은 언어 모델과 프롬프트 템플릿을 연결하여 체인을 구성합니다.
  • SequentialChain은 여러 체인을 순차적으로 실행할 수 있게 합니다.
  • input_variablesoutput_variables는 체인에 전달할 입력과 받을 출력을 지정합니다.
  • verbose=True는 체인의 실행 과정을 상세히 출력합니다.

4. 소설 생성 함수 정의

  • generate_story 함수는 스타일과 주제를 입력받아 체인을 실행하고 결과를 반환합니다.
  • sequential_chain에 필요한 입력을 딕셔너리 형태로 전달합니다.
  • 결과는 딕셔너리로 반환되며, "text" 키에 생성된 소설 문장이 담겨 있습니다.

5. 예제 실행

  • styletopic 변수를 정의하여 원하는 스타일과 주제를 지정합니다.
  • generate_story 함수를 호출하여 소설의 첫 문장을 생성합니다.
  • 결과를 출력합니다.

🧑‍🔬 이론적 배경

  • 언어 모델(LLM): 대규모 데이터로 학습한 모델로, 자연어 생성 및 이해 능력을 갖추고 있습니다. GPT-3.5-turbo는 OpenAI에서 제공하는 강력한 언어 모델입니다.
  • 프롬프트 엔지니어링: 모델에게 원하는 결과를 얻기 위해 프롬프트를 설계하는 과정입니다. 프롬프트의 구조와 내용에 따라 모델의 출력이 크게 달라집니다.
  • 체인(chain): LangChain에서 체인은 여러 모델 호출을 연결하여 복잡한 작업을 수행할 수 있게 해줍니다.
  • 메모리(memory): 대화나 문맥을 유지하기 위해 이전 정보를 저장하는 메커니즘입니다.

🔍 4. 주요 설명

🖥️ 모델 I/O

  • 입력: 프롬프트 템플릿과 사용자가 지정한 스타일, 주제.
  • 출력: 모델이 생성한 소설의 첫 문장.
  • 역할: 모델은 입력받은 프롬프트를 기반으로 적절한 출력을 생성합니다.

📊 데이터

  • 프롬프트 템플릿: 모델에게 작업을 지시하는 역할을 합니다.
  • 입력 변수: {style}, {topic}은 사용자가 입력하는 데이터입니다.

🔗 체인

  • LLMChain: 프롬프트와 모델을 연결하여 텍스트를 생성합니다.
  • SequentialChain: 여러 체인을 순차적으로 실행할 수 있게 합니다. 이 예제에서는 하나의 체인만 사용하지만, 필요에 따라 확장 가능합니다.

💾 메모리

  • ConversationBufferMemory: 이전 대화나 생성된 텍스트를 저장하여 컨텍스트를 유지합니다.
  • 역할: 모델이 이전 생성 내용을 참고하여 일관성 있는 출력을 생성하도록 돕습니다.

🕵️ 에이전트

  • 역할: LangChain에서 에이전트는 복잡한 작업을 수행하기 위해 체인을 관리하고 조정하는 역할을 합니다.
  • 이 예제에서: 소설 작성을 위한 체인이 에이전트의 역할을 수행합니다.

🤔 5. 추가적인 고려 사항

  • 데이터 전처리: 소설 데이터를 직접 학습시키려면 데이터의 품질과 형식이 중요합니다. 텍스트 정제, 중복 제거 등의 전처리가 필요할 수 있습니다.
  • 데이터베이스 연결: 대량의 소설 데이터를 관리하려면 데이터베이스를 활용하여 효율적으로 데이터를 저장하고 검색할 수 있습니다.
  • 모델 파인튜닝: OpenAI의 파인튜닝 기능을 활용하여 특정 스타일이나 주제에 특화된 모델을 만들 수 있습니다.
  • 성능 최적화: 모델의 응답 시간이나 비용을 고려하여 캐싱, 배치 처리 등의 방법을 도입할 수 있습니다.

📂 txt 파일 사용

txt 파일에서 소설 데이터를 불러와 프롬프트에 참고하는 방식으로 구현하면, 모델이 특정 스타일이나 내용에 기반하여 텍스트를 생성하도록 유도할 수 있습니다.

📝 코드 업데이트: txt 파일에서 데이터 가져오기

📄 1. 소설 데이터 파일 준비

  • 소설 텍스트를 novel_data.txt 파일에 저장합니다.
  • 파일은 프로젝트 디렉토리에 위치해야 하며, UTF-8 인코딩을 사용해야 합니다.

🖥️ 2. 수정된 LangChain 코드

import os
from langchain import OpenAI, PromptTemplate, LLMChain
from langchain.chains import SequentialChain
from langchain.memory import ConversationBufferMemory
from dotenv import load_dotenv

# .env 파일에서 API 키 로드
load_dotenv()
openai_api_key = os.getenv("OPENAI_API_KEY")

# 1. OpenAI 모델 초기화
llm = OpenAI(api_key=openai_api_key, model="gpt-3.5-turbo")

# 2. txt 파일에서 소설 데이터 읽기
def load_novel_data(file_path: str) -> str:
    with open(file_path, 'r', encoding='utf-8') as file:
        novel_data = file.read()
    return novel_data

novel_data_path = "novel_data.txt"  # txt 파일 경로
novel_data = load_novel_data(novel_data_path)

# 3. 프롬프트 템플릿 설정 (참고 데이터 포함)
prompt_template = """
당신은 {style} 스타일의 소설 작가입니다. 다음 소설 내용을 참고하여 비슷한 스타일로 새로운 소설의 첫 문장을 작성하세요.

참고 소설 내용:
"{novel_data}"

주제: {topic}
"""

# 4. 체인과 메모리 설정
memory = ConversationBufferMemory()

prompt_chain = PromptTemplate(
    template=prompt_template, input_variables=["style", "topic", "novel_data"]
)
llm_chain = LLMChain(llm=llm, prompt=prompt_chain, output_key="text")

sequential_chain = SequentialChain(
    chains=[llm_chain],
    input_variables=["style", "topic", "novel_data"],
    output_variables=["text"],
    memory=memory,
    verbose=True
)

# 5. 소설 생성 함수 정의
def generate_story(style: str, topic: str, novel_data: str):
    result = sequential_chain({"style": style, "topic": topic, "novel_data": novel_data})
    return result["text"]

# 6. 예제 실행
style = "고풍스러운 문체와 서정적 어휘"
topic = "운명에 의해 갈라진 연인들의 이야기"

story = generate_story(style, topic, novel_data)
print(story)

📌 상세 설명

1. 소설 데이터 읽기

  • load_novel_data 함수는 지정된 경로의 텍스트 파일을 읽어와 문자열로 반환합니다.
  • encoding='utf-8'로 지정하여 한글이 정상적으로 읽히도록 합니다.
  • novel_data 변수에 파일의 내용을 저장합니다.

2. 프롬프트 템플릿 수정

  • novel_data를 프롬프트에 포함하여 모델이 참고할 수 있도록 합니다.
  • 모델은 참고 소설 내용을 기반으로 유사한 스타일의 새로운 문장을 생성합니다.

3. 체인 입력 변수 추가

  • input_variablesnovel_data를 추가하여 체인에 전달합니다.
  • generate_story 함수에서도 novel_data를 인수로 받도록 수정합니다.

🧑‍🔬 이론적 배경

  • 컨텍스트 기반 생성: 모델에게 참고할 텍스트를 제공하면, 해당 텍스트의 스타일, 어휘, 문체 등을 학습하여 유사한 출력을 생성할 수 있습니다.
  • 프롬프트 엔지니어링의 중요성: 프롬프트에 어떤 정보를 어떻게 포함시키느냐에 따라 모델의 출력 품질이 크게 달라집니다.

💡 주요 업데이트 설명

  • load_novel_data 함수: 외부 파일에서 데이터를 읽어와 프로그램 내에서 활용할 수 있게 해줍니다.
  • 프롬프트 템플릿: 참고할 소설 내용을 포함하여 모델에게 구체적인 지시를 내립니다.
  • 체인 실행 시 novel_data 전달: 체인에 추가적인 입력을 전달하여 프롬프트에 반영되도록 합니다.

🦙 Ollama를 사용한 Llama 모델 활용

Ollama를 사용하여 Llama 2 모델을 활용해 소설 데이터를 학습하고 유사한 스타일의 소설을 작성하는 코드를 구현할 수 있습니다.

🚀 1. 가상 환경 설정 및 필수 패키지 설치

python3 -m venv myenv
source myenv/bin/activate  # Windows의 경우: myenv\Scripts\activate
pip install langchain python-dotenv langchain-ollama
  • langchain-ollama 패키지는 LangChain과 Ollama를 통합하여 사용할 수 있게 해줍니다.

📥 2. Ollama 설치 및 Llama 3.2 모델 다운로드

# Ollama 설치
curl -fsSL https://ollama.ai/install.sh | sh

# Llama 3.2 모델 다운로드
ollama pull llama3.2

#llama 3.2 실행
ollama run llama3.2
  • Ollama는 로컬에서 대형 언어 모델을 실행할 수 있게 해주는 도구입니다.
  • ollama pull llama2를 통해 Llama 3.2 모델을 로컬에 다운로드합니다.

🔑 3. .env 파일 설정

Ollama는 로컬에서 실행되므로 별도의 API 키는 필요하지 않습니다.

🧠 4. LangChain 코드 구현

import os
from langchain import PromptTemplate, LLMChain
from langchain.chains import SequentialChain
from langchain.memory import ConversationBufferMemory
from dotenv import load_dotenv
from langchain_ollama import OllamaLLM

# .env 파일 로드
load_dotenv()

# 1. Ollama 모델 초기화
llm = OllamaLLM(model="llama3.2")

# 2. txt 파일에서 소설 데이터 읽기
def load_novel_data(file_path: str) -> str:
    with open(file_path, 'r', encoding='utf-8') as file:
        novel_data = file.read()
    return novel_data

novel_data_path = "./nbtosung.txt"  # txt 파일 경로
novel_data = load_novel_data(novel_data_path)

# 3. Prompt Template 설정 (참고 데이터 포함)
prompt_template = """
당신은 {style} 스타일의 소설 작가입니다. 다음 소설 내용을 참고하여 비슷한 스타일로 새로운 소설의 첫 문장을 작성하세요.

참고 소설 내용:
"{novel_data}"

주제: {topic}
"""

# 4. 체인과 메모리 설정
# memory를 prompt와 연관된 변수를 제외하고, 필요한 데이터만 저장하도록 변경
memory = ConversationBufferMemory(memory_key="memory_buffer", input_key="topic")

prompt_chain = PromptTemplate(
    template=prompt_template, input_variables=["style", "topic", "novel_data"]
)
llm_chain = LLMChain(llm=llm, prompt=prompt_chain, output_key="text")

# 최종 체인 설정
sequential_chain = SequentialChain(
    chains=[llm_chain],
    input_variables=["style", "topic", "novel_data"],
    output_variables=["text"],
    memory=memory,
    verbose=True
)

# 5. 소설 생성 함수 정의
def generate_story(style: str, topic: str, novel_data: str):
    result = sequential_chain({"style": style, "topic": topic, "novel_data": novel_data})
    return result["text"]

# 6. 예제 실행
style = "고풍스러운 문체와 서정적 어휘"
topic = "운명에 의해 갈라진 연인들의 이야기"

story = generate_story(style, topic, novel_data)
print(story)

📌 상세 설명

1. Ollama 모델 초기화

  • Ollama 클래스를 사용하여 Llama 3.2 모델을 초기화합니다.
  • model 파라미터에 사용할 모델의 이름을 지정합니다.

2. 패키지 설치

  • langchain-ollama 패키지를 설치하여 LangChain에서 Ollama 모델을 사용할 수 있게 합니다.

3. 나머지 코드는 이전 섹션과 동일

  • 소설 데이터 로드, 프롬프트 템플릿 설정, 체인 구성 등은 이전과 동일합니다.

🧑‍🔬 이론적 배경

  • 로컬 모델 사용의 장점: 데이터 프라이버시 보호, 인터넷 연결 불필요, 비용 절감 등의 이점이 있습니다.
  • Ollama의 역할: 로컬에서 대형 언어 모델을 실행하고 관리할 수 있게 해주는 도구입니다.

🔄 주요 변경 사항

  • Ollama 모델 초기화: OpenAI 모델 대신 Ollama를 통해 로컬에서 모델을 실행합니다.
  • 패키지 설치: langchain-ollama 패키지를 통해 LangChain과 Ollama의 통합을 지원합니다.

📝 참고 사항

  • 시스템 요구 사항: 로컬에서 대형 언어 모델을 실행하려면 고성능의 GPU와 충분한 메모리가 필요합니다.
  • 라이선스 확인: Llama 2 모델은 Meta에서 공개한 모델로, 상업적 사용 등에는 라이선스 조건을 확인해야 합니다.

이렇게 LangChain과 Ollama를 활용하여 로컬에서 소설 데이터를 기반으로 유사한 스타일의 소설을 생성하는 시스템을 구축할 수 있습니다. 이를 통해 데이터 프라이버시를 유지하면서도 강력한 언어 생성 능력을 활용할 수 있습니다.

profile
IT를 좋아합니다.

0개의 댓글