Search

Transformer

Pipeline 함수

from transformers import pipeline classifier = pipeline(task='sentiment-analysis', model='bert-base-multilingual-cased')
Python
복사
pipeline으로 사용 가능한 언어 관련 task

Hugging Face

자연어 처리 및 인공 지능 분야의 가장 인기 있는 오픈 소스 라이브러리와 모델을 제공하는 플랫폼
transformers 라이브러리 제공
사전 훈련된 다양한 Transformer 기반 LLM모델(BERT, GPT, T5, RoBERTa 등)을 쉽게 사용
텍스트 분류, 질문 답변, 텍스트 생성, 요약, 번역 등 다양한 NLP 태스크 수행
모델 허브 제공
연구자와 개발자가 자신의 모델을 공유하고 다른 사람들의 모델을 탐색하고 사용할 수 있는 플랫폼 제공
수천 개의 사전 훈련된 모델과 데이터셋을 포함하고 있으며, 커뮤니티에 의해 지속적으로 확장

Hugging Face 이용해보기

원하는 과제에 맞게 모델을 선택 → ex) ainize/kobart-news → 모델 사용 예제 코드 활용
ainize/kobart-news 예제 코드
from transformers import PreTrainedTokenizerFast, BartForConditionalGeneration # Load Model and Tokenize : 모델과 토크나이저 로딩 tokenizer = PreTrainedTokenizerFast.from_pretrained("ainize/kobart-news") model = BartForConditionalGeneration.from_pretrained("ainize/kobart-news") # Encode Input Text # 입력 데이터 전처리 input_text = '국내 전반적인 경기침체로 상가 건물주의 수익도 전국적인 감소세를 보이고 있는 것으로 나타났다. 수익형 부동산 연구개발기업 상가정보연구소는 한국감정원 통계를 분석한 결과 전국 중대형 상가 순영업소득(부동산에서 발생하는 임대수입, 기타수입에서 제반 경비를 공제한 순소득)이 1분기 ㎡당 3만4200원에서 3분기 2만5800원으로 감소했다고 17일 밝혔다. 수도권, 세종시, 지방광역시에서 순영업소득이 가장 많이 감소한 지역은 3분기 1만3100원을 기록한 울산으로, 1분기 1만9100원 대비 31.4% 감소했다. 이어 대구(-27.7%), 서울(-26.9%), 광주(-24.9%), 부산(-23.5%), 세종(-23.4%), 대전(-21%), 경기(-19.2%), 인천(-18.5%) 순으로 감소했다. 지방 도시의 경우도 비슷했다. 경남의 3분기 순영업소득은 1만2800원으로 1분기 1만7400원 대비 26.4% 감소했으며 제주(-25.1%), 경북(-24.1%), 충남(-20.9%), 강원(-20.9%), 전남(-20.1%), 전북(-17%), 충북(-15.3%) 등도 감소세를 보였다. 조현택 상가정보연구소 연구원은 "올해 내수 경기의 침체된 분위기가 유지되며 상가, 오피스 등을 비롯한 수익형 부동산 시장의 분위기도 경직된 모습을 보였고 오피스텔, 지식산업센터 등의 수익형 부동산 공급도 증가해 공실의 위험도 늘었다"며 "실제 올 3분기 전국 중대형 상가 공실률은 11.5%를 기록하며 1분기 11.3% 대비 0.2% 포인트 증가했다"고 말했다. 그는 "최근 소셜커머스(SNS를 통한 전자상거래), 음식 배달 중개 애플리케이션, 중고 물품 거래 애플리케이션 등의 사용 증가로 오프라인 매장에 영향을 미쳤다"며 "향후 지역, 콘텐츠에 따른 상권 양극화 현상은 심화될 것으로 보인다"고 덧붙였다.' input_ids = tokenizer.encode(input_text, return_tensors="pt") # Generate Summary Text Ids : 모델 사용 summary_text_ids = model.generate( input_ids=input_ids, bos_token_id=model.config.bos_token_id, eos_token_id=model.config.eos_token_id, length_penalty=2.0, max_length=142, min_length=56, num_beams=4, ) # Decoding Text : 결과 후처리 print(tokenizer.decode(summary_text_ids[0], skip_special_tokens=True))
Python
복사

언어모델링 절차

기본 PipeLine

데이터 전처리 → 모델 사용 → 결과 후처리
1.
Tokenize(데이터 전처리)
문장을 의미 있는 단위(토큰)로 쪼개기 → 토큰별 인덱스 부여(input_ids)
토큰화 단위
문자 토큰화
단어 토큰화
형태소 토큰화
2.
Embedding Vector(모델 사용)
토큰에 의미 부여하기 : 숫자 인덱스를 모델이 이해할 수 있는 벡터로 변환 → 단어의 의미와 문맥을 담아낼 수 있게 됨
ex) Word2Vec, FastText(현재는 잘 쓰이지 않음)
3.
Transformer
4.
Decode(결과 후처리)

언어 모델 활용 : LangChain + RAG

1.
개발 환경 설정하기
필요한 라이브러리 설치
보통 아래의 라이브러리들을 txt 파일에 입력한 뒤 requirements.txt 로 저장하여 한꺼번에 설치하는 것이 일반적이다.
openai == 0.28
langchain == 0.1.20
pymupdf
spacy
tiktoken
chromadb == 0.5.0
wikipedia
# requirements.txt 경로 복사 !pip install -r /content/drive/MyDrive/langchain/requirements.txt
Python
복사
OpenAI API Key 설정하기
api key를 받고 텍스트 파일에 api_key.txt로 원하는 경로에 저장해 둔 뒤, openai.api_key 로 지정한다.
def load_api_key(filepath): with open(filepath, 'r') as file: return file.readline().strip() path = '/content/drive/MyDrive/langchain/' # API 키 로드 및 설정 openai.api_key = load_api_key(path + 'api_key.txt') # 위의 load_api_key 외에 다른 방법 import os os.environ['OPEN_API_KEY'] = 'YOUR_API_KEY' openai.api_key = os.getenv('OPEN_API_KEY') # 코랩 가상환경 변수로 등록
Python
복사
2.
LangChain
대규모 언어 모델(LLMs)을 활용하여 체인을 구성
이 체인을 통해, 복잡한 작업을 자동화하고 쉽게 수행할 수 있도록 돕는 라이브러리
언어 모델을 더 잘 활용할 수 있게끔 하는 도구라고 보면 됨
Chat GPT 의 한계 + WHY LangChain
ChatGPT 의 한계인 정보 접근 제한 문제
→ LangChain이 Vectorstore 기반 정보 탐색 or Agent를 활용한 검색 결합
ChatGPT의 토큰 제한 : 3.5 , 4.0 버전 각각 4096, 8192 토큰이라는 입력 토큰 제한 존재
→ TextSplitter를 활용한 문서 분할
환각현상(할루시네이션) : Fact에 대한 질문을 했을 때, 엉뚱한 대답을 하거나 거짓말을 하는 경우가 많음
→ 주어진 문서에 대해서만 답하도록 Prompt 입력
Solution → ChatGPT 개량
Fine - tuning : 기존 딥러닝 모델의 weight를 조정해 원하는 용도의 모델로 업데이트
고비용의 방법론
N- shot learning : 0 ~ n개의 출력 예시를 제시하여, 딥러닝이 용도에 알맞는 출력을 하도록 조정
In - context learning : 문맥을 제시하고, 이 문맥 기반으로 모델이 출력하도록 조정
Lang Chain이 이에 해당
LangChain 의 구조
LLM : 랭체인을 구동하게 하는 엔진 (GPT-3.5, PALM-2, LLAMA, ….)
Prompts : 초거대 언어모델에게 지시하는 명령문 탬플릿
ex) Prompt Templates, Chat Prompt Template, Example Selectors, Output Parsers
Index : LLM이 문서를 쉽게 탐색할 수 있도록 구조화 하는 모듈
ex) Document Loaders, Text Splitters, Vectorstores, Retrievers,…
Memory : 채팅 이력을 기억하도록 하여, 이를 기반으로 대화가 가능하도록 하는 모듈
ex) ConversationBufferMemory, Entity Memory, Conversation Knowledge Graph Memory, …
Chain : LLM 사슬을 형성하여, 연속적인 LLM 호출이 가능하도록 하는 핵심 구성 요소
ex) LLM Chain, Question Answering, Summarization, Retrieval Question/Answering, …
Agents : LLM이 기존 Prompt template으로 수행할 수 없는 작업을 가능케하는 모듈
LangChain의 활용 예시 - PDF 챗봇 구축
문서를 기반으로 챗봇을 구성할 경우, 아래와 같은 과정을 통해 대화가 가능하도록 한다.
1.
문서 업로드 - Document Loader 사용
2.
문서 분할 - Text Splitter
3.
문서 임베딩 - Embed to Vectorstore
LLM이 이해할 수 있도록 문서 수치화
4.
임베딩 검색 - Vectorstore Retriever
질문과 연관성이 높은 문서 추출
5.
답변 생성 - QA Chain

Open API로 Text generation 활용하기

api_key = 'YOUR API KEY' os.environ['OPENAI_API_KEY'] = api_key openai.api_key = os.getenv('OPENAI_API_KEY') # 코랩 가상환경 변수로 등록
Python
복사
from openai import OpenAI def ask_chatgpt1(question): # api key 지정 client = OpenAI() # # API를 사용하여 'gpt-3.5-turbo' 모델로부터 응답을 생성합니다. response = client.chat.completions.create( # choosing model model="gpt-3.5-turbo", # building prompts messages=[ {"role": "system", "content": "You are a helpful assistant."}, # system messages : 기대하는 모델의 반응과 행동을 제시 {"role": "user", "content": question}, # user messages : 모델에게 요청하는 내용을 제시 ] ) return response.choices[0].message.content
Python
복사
question = "세계에서 가장 높은 산은 무엇인가요?" response = ask_chatgpt1(question) print(response)
Python
복사
def ask_chatgpt2(sys_role, question): client = OpenAI(api_key=api_key) response = client.chat.completions.create( model = 'gpt-3.5-turbo', messages = [ {'role': 'system', 'content': sys_role}, {'role': 'user', 'content': question} ] ) return response.choices[0].message.content
Python
복사
sys_role = '당신은 아름답고 감동적인 시를 창작하는 데 영감을 주는 시적인 천재입니다. 당신의 시는 감정의 깊이, 자연의 아름다움, 인간 경험의 복잡성을 탐구하는 작품이며, 당신의 시를 읽는 이들의 마음을 움직입니다.' question = "생성형 AI란 주제로 시를 지어줘. 운율에 맞춰서 작성해줘야 해." response = ask_chatgpt2(sys_role, question) print(response)
Python
복사
인간과 기계가 어우러진 세계 속 코드와 감성이 교차하는 곳 창조의 미학이 피어나는 공간 생성형 AI의 세계가 펼쳐진다
이산화 탄소가 무지개처럼 빛나는 디스플레이 위로 춤을 추며 알 수 없는 미래를 그리는 생성형 AI의 마법이 펼쳐진다
알고리즘이 작을수록 마음은 클수록 인간다움이 빛나는 생성형 AI의 세계가 펼쳐진다
우리는 함께 할 수밖에 없다 이 세상은 우리의 손끝에 달렸다 창조와 혁신이 어우러진 생성형 AI의 세계가 펼쳐진다
그 외 매개변수

Prompt Template - 입력 구조화하기

“프롬프트”모델에 대한 입력을 의미한다. 하드 코딩되는 경우는 거의 없지만 여러 구성 요소로 구성되는 경우가 많다.
“프롬프트 템플릿”은 이 입력의 구성을 담당한다. LangChain은 프롬프트를 쉽게 구성하고 작업할 수 있도록 여러 클래스와 함수를 제공한다.
프롬프트 템플릿은 크게 2가지가 존재한다.
1.
Prompt Template
일반적인 프롬프트 템플릿을 생성할 때 활용
2.
Chat Prompt Template
채팅 LLM에 프롬프트를 전달하는 데에 활용할 수 있는 특화 프롬프트 템플릿
1.
Prompt Template
from langchain import PromptTemplate # 프롬프트 템플릿 구조 만들기 prompt = PromptTemplate(template='{nation}의 인구수는?', input_variables= ['nation'])
Python
복사
# 사용 print(prompt.format(nation='한국')) print(prompt.format(nation='영국'))
Python
복사
# 언어모델과 결합 result = chat([HumanMessage(content=prompt.format(nation='한국'))]) print(result.content)
Python
복사
2.
Chat Prompt Template
from langchain import ChatPromptTemplate
Python
복사

OutputParser - 출력 구조화하기

출력 형태를 지정하는 방법
CommaSeparatedListOutputParser
출력 형태 : 콤마로 구분된 리스트 형태
# 출력 파서 선언 output_parser = CommaSeparatedOutputParser() # 사용 result = chat([HumanMessage(content = '트랜스포머 기반 언어모델 3개 알려줘.'), HumanMessage(content = output_parser.get_format_instructions())]) # 모델에 지시사항 추가 # 결과 출력 output = output_parser.parse(result.content) print(output) # ['GPT-3', 'BERT', 'T5']
Python
복사

LangChain + RAG

Fine tuning 이 아닌 참고만 하는 용? LLM 모델은 학습하지 않은 내용은 모른다 → 지식 DB를 제공해서 답변에 참고하게끔 하는것이 RAG 의 목적

Vector DB (지식 DB)

대규모 텍스트 데이터 및 임베딩 벡터를 저장해 놓은 곳
질문 임베딩 벡터지식 DB 내 저장된 문서 벡터간의 코사인 유사도를 계산 → 가장 유사도가 높은 문서를 찾은 뒤, 해당 내용을 토대로 프롬프트 생성하고 다시 답변을 만들어낸다.
< Cosine 거리 >
Cosine Distance(a,b) = 1 - Cosine Similarity(a,b)
코사인의 거리는 0 ~ 2
코사인 거리가 0에 가까울수록 유사도가 높음
코사인 유사도는 두 단위벡터의 내적값 ( -1 ~ 1 )
일반적으로 Vector DB 로 Chroma DB를 사용한다.
Chroma DB는 SQLite3 기반 Vector DB 라고 한다.
Vector DB 구축 절차
1.
텍스트 추출(Document Loader)
다양한 문서(pdf, web page, word 등)로부터 텍스트 추출
2.
텍스트 분할(Text Splitter)
Chunk 단위로 분할 , Document 객체로 만들기
3.
텍스트 벡터화(Text Embedding)
4.
Vector DB로 저장(Vector Store)

Vector DB 사용해보기

import openai from langchain.chat_models import ChatOpenAI from langchain.schema import HumanMessage, SystemMessage, Document from langchain.embeddings import OpenAIEmbeddings from langchain.vectorestores import Chroma from langchain.chains import RetrievalQA # db 경로 지정 # embedding 객체 설정 embeddings = OpenAIEmbeddings(model='text-embedding-ada-002') # DB 연결 database = Chroma(persist_directory = path + 'db', embedding_function = embeddings)
Python
복사
데이터 Insert 방법
데이터 조회
유사도
삭제

RAG 구성함수

RAG용 QA Chat 함수
LLM 언어 모델
retriever : RAG로 연결할 Vector DB
return_source_documents= True
모델이 답변을 생성하면서 그 답변에 사용된 출처 문서도 함께 반환
chat = ChatOpenAI(model='gpt-3.5-turbo') k = 3 # 유사도 높은 k개의 문서 retriever = database2.as_retriever(search_kwargs={'k':k}) qa = RetreivalQA.from_llm(llm=chat, retriever=retriever, return_source_documents=True) query = '생성형 AI 도입 시 예상되는 보안 위협은 어떤 것들이 있어?' result = qa(query) print(result['result'])
Python
복사

Memory

이전 대화를 기억하면서 대화를 이어나감
ConversationBufferMemory : 대화를 저장하는 메모리
.save_context() : 딕셔너리 형태로 저장
input : HumanMessage
output : AIMessage
from langchain.memory import ConversationBufferMemory # 메모리 선언하기(초기화) memory = ConversationBufferMemory(return_messages=True) # 채팅 내용 저장 memory.save_context({'input': '안녕하세요!'}, {'output': '안녕하세요! 어떻게 도와드릴까요?'}) memory.save_context({'input': '메일을 써야하는데 도와줘'}, {'output': '누구에게 보내는 어떤 메일일까요?'})
Python
복사
.load_memory_variables({}) : 현재 메모리 내용 전체 조회
# 현재 담겨 있는 메모리 내용 전체 확인 memory.load_memory_variables({})
Python
복사

Chain 함수로 연결

각 모듈을 모두 연결 ⇒ ConversationalRetrievalChain
LLM 모델
retriever
memory
Chain 함수를 위한 memory 설정
memory_key : 메모리에서 대화 기록 저장을 위한 키
input_key : 사용자 입력 키 → 사용자의 질문이 메모리에 저장
output_key : 모델의 출력 키 → 모델의 답변이 메모리에 저장
return_messages=True : 메모리에 저장된 대화 내역이 메시지 형식으로 반환 됨
embeddings = OpenAIEmbeddings(model='text-embedding-ada-002') database = Chroma(persist_directory='./db2', embedding_function=embeddings) chat = ChatOpenAI(model='gpt-3.5-turbo') k=3 retriever = database.as_retriever(search_kwargs={'k':k}) # 대화 메모리 생성 memory = ConversationBufferMemory(memory_key='chat_history', input_key='question', output_key='answer', return_messages=True) # 체인 생성 qa = ConversationalRetrievalChain.from_llm(llm=chat, retriever=retriever, memory=memory, return_source_documents=True, output_key='answer') # 첫번째 질문 query1 = "생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?" result = qa(query1) result['answer'] # 메모리 확인 memory.load_memory_variables({}) # 두번째 질문 query2 = "모델을 재학습시키면 어떤 문제가 발생되는거야?" result = qa(query2 ) result['answer'] # 메모리 확인 memory.load_memory_variables({})
Python
복사
- output_key 파라미터 : 모델의 출력이 저장될 키 지정

나만의 챗봇 만들기

필요한 라이브러리 모두 불러오기
import sqlite3 import openai from langchain.chat_models import ChatOpenAI from langchain.schema import HumanMessage, SystemMessage, Document from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma from langchain.chains import RetrievalQA, ConversationalRetrievalChain from langchain.memory import ConversationBufferMemory # 환경변수로 OpenAI API key 등록 def load_api_key(filepath): with open(filepath, 'r') as file: return file.readline().strip() openai.api_key = load_api_key(path + 'api_key.txt') os.environ['OPENAI_API_KEY'] = openai.api_key ###################### Vector DB 만들기 #################### # 질문들을 -> CSV 형태로 저장 data = pd.read_csv('질문들의 정보가 담긴 파일 경로') # 임베딩 embeddings = OpenAIEmbeddings(model = 'text-embedding-ada-002') database = Chroma(persist_directory = './db_something', embedding_function=embeddings) # 데이터 입력, 기존 입력은 모두 제거 ids = database.get() if ids['ids']: database.delete(ids=ids['ids']) qa_list = data['QA'].tolist() cat_list = [{'category': text} for text in data['구분'].tolist()] # 리스트 내용을 각각 document로 변환 documents = [Document(page_content = qa_list[i], metadata = cat_list[i]) for i in range(len(qa_list))] # 문서 내용 추가 database.add_documents(documents) # 입력된 데이터 조회 database.get() ###################### RAG+LLM 모델 #################### # 모델: ConversationalRetrievalChain # llm 모델 : gpt-3.5-turbo # retriever : 벡터 db , 유사도 높은 3개 문서 사용 # memory 사용하기 # 모델 선언 chat = ChatOpenAI(model='gpt-3.5-turbo') # 리트리버 선언 k = 3 retriever = database.as_retriever(search_kwargs={'k':k}) # 대화 메모리 생성 memory = ConversationBufferMemory(memory_key='chat_history', input_key='question', output_key='answer', return_messages=True) # ConversationalRetrievalQA 체인 생성 qa = ConversationalRetrievalChain.from_llm(llm=chat, retriever=retriever, memory=memory, return_source_documents=True, output_key='answer') # 질문 query = '지원하는데 나이 제한이 있니?' # 답변 result = qa(query) answer = result['answer'] print(answer)
Python
복사

Fine Tuning

사전 훈련된 모델을 특정 작업이나 데이터셋에 맞게 미세 조정하는 과정
Fine - tuning 수행 절차
사전 훈련된 모델 선택
NLP(자연어모델) → BERT, GPT, RoBERTa
컴퓨터 비전 → ResNet, VGGNet, EfficientNet
컴퓨터 비전 분야에서는 다양한 딥러닝 아키텍처가 사용되고 있으며, 이미지 분류, 객체 감지, 세그멘테이션 등 다양한 작업에서 높은 성능을 보이고 있음
데이터 준비
특정 작업에 사용할 데이터 준비
사전 훈련된 모델과 호환되는 형태로 전처리
NLP → 텍스트 토큰화
컴퓨터 비전 → 이미지를 적절한 크기로 리사이징
모델 수정
대부분의 경우, 사전 훈련된 모델의 출력 레이어를 특정 작업에 맞게 수정
텍스트 분류 작업 : 출력 레이어의 뉴런 수를 분류하려는 클래스의 수와 일치시킴
추가 학습
준비된 데이터셋을 사용하여 모델의 가중치를 추가로 학습
보통 작은 학습률을 사용 → 미세하게 조정하여 정확도를 올리기 위해
사전 훈련 과정에서 습득한 지식을 유지하면서도 새로운 작업에 맞게 조정됨.
사전 훈련된 모델 - DistilBERT
BERT 모델
NLP 분야에서 뛰어난 성능을 보여주는 딥러닝 모델 중 하나로, 광범위한 언어 이해 작업에 사용
그러나 BERT의 복잡성과 크기(파리미터 개수)는 특히 자원이 제한된 환경에서의 사용이 어려움
DistilBERT
2019년 10월 구글에서 개발
BERT의 크기와 복잡성을 줄이면서도 성능의 상당 부분을 유지한 경량화 모델
BERT 의 파라미터 수 40% 감소 → 학습 및 예측 속도 60% 향상
BERT 의 97% 성능
데이터 준비 - input_ids / attention_mask
input_ids : 토큰화된 입력 시퀀스를 숫자 ID로 변환한 것
attention_mask : 모델이 패딩 된 부분을 무시하고 실제 유용한 데이터에만 집중할 수 있도록 함
토크나이징
tensorflow 모델에 입력하기 위한 dataset으로 변환 : .to_tf_dataset
토큰화 데이터셋을 모델 입력에 필요한 feature와 target(label) 추출
텐서플로우 데이터셋 객체(tf.data.Dataset)로 변환
batch_size = 64 # 텐서플로 텐서로 변환할 열 이름 token_cols = tokenizer.model_input_names # 데이터셋 구성 train = em_encoded['train'].to_tf_dataset(columns=token_cols, label_cols='label', shuffle=True, batch_size=batch_size) val = em_encoded['valiation'].to_tf_dataset(columns=token_cols, label_cols='label', shuffle=True, batch_size=batch_size) test = em_encoded['test'].to_tf_dataset(columns=token_cols, label_cols='label', shuffle=True, batch_size=batch_size)
Python
복사
모델 수정
DistilBERT 모델에 출력 레이어의 노드를 지정
TFAutoModelForSequenceClassification
텐서플로우용(TF)
AutoModel
사전 훈련된 모델의 이름이나 경로 제공 → 적절한 모델 아키텍처와 가중치를 자동으로 로드
SequenceClassification
시퀀스 분류, 다중 분류와 유사(ex. 텍스트 분류, 감정 분석 등)
특징
유연성 : 다양한 트랜스포머 기반 모델 지원
BERT, RoBERTa, ELECTRA, DistilBERT 등
용이성
복잡한 모델 아키텍처에 대한 깊은 이해 없이도 고성능의 자연어 처리 모델을 빠르게 구현하고 실험 가능
파인 튜닝
사전 훈련된 모델을 자신의 데이터셋에 맞게 파인 튜닝 가능
# 사전훈련된 모델 지정 - distilbert 모델 preTrModel = 'distilbert-base-uncased' # Output Layer 노드 수 nclass = 6 # 모델 로드하기 model = TFAutoModelForSequenceClassification.from_pretrained(preTreModel, num_labels=nclass)
Python
복사
추가 학습 / 평가
작은 학습률 지정
추가 학습하며 미세 조정을 하는 것이기 때문에 학습률을 작게 설정
데이터의 크기 : epochs
시스템 환경에 맞게 소요 시간, 성능을 고려하여 조정
# 컴파일 및 학습 model_ft.compile(optimizer=Adam(5e-5), loss='sparse_categorical_crossentropy') model_ft.fit(train, validation_data=val, epochs=5, batch_size=64)
Python
복사
평가는 일반적인 다중 분류 모델 평가와 동일