[Gemma2 모델을 이용한 유튜브 실시간 채팅 요약 프로젝트] 2) Chat Summarization with LLM
안녕하세요.
Gemma2 모델을 이용한 유튜브 실시간 채팅 요약 프로젝트 2번째 포스팅입니다.
이전 유튜브 채팅 데이터 Crawling 포스팅에 이어서
가져온 채팅 데이터를 LLM 모델에 넣고
채팅 요약 및 분석을 하는 과정을 설명하겠습니다.
1. 모델 선택 기준 생각하기
사용할 모델을 따져보았습니다.
1-1. Gemma Sprint의 프로젝트이므로 Gemma 모델을 사용합니다.
Gemma 모델은 Opensource 모델이므로 비용이 소모되지 않습니다.짱짱
1-2. 하지만 Opensource 모델인 만큼 개발 컴퓨터 환경에서 추론이 가능해야 합니다.
저의 컴퓨터 환경은 24GB RAM을 가진 GPU를 사용하고 있습니다.
과연 돌아갈지는 테스트를 진행하면서 확인해보겠습니다.
1-2. 프로젝트 방향성을 따졌을 때 채팅데이터는 한국어와 영어가 대부분을 차지했습니다.
한국어와 영어가 가능한 모델이어야 합니다.
3가지 조건을 따졌을 때,
HuggingFace에 올라온 Gemma Korean Fine-tuning model인
이준범님의 gemma-k0-2b 모델과 returnzero사의 ko-gemma-2-9b-it 모델이 적합해 보였습니다.
(편하게 사용할 수 있게 공유주셔서 감사합니다..)
2. 프롬프트 만들기
ChatGPT를 이용해서 여러개의 프롬프트를 추천받았습니다.
1) 3개의 요약 내용을 노출함
2) 요약 예시는 부드럽고 친근하되 존댓말로 나왔으면 함
3)대화의 흐름을 시간순으로 파악함
4)긍정과 부정에 대한 값이 전체 비율이 100% 에서 "긍정:xx/부정xx"로 출력
추천 받은 프롬프트를 위의 기준으로 다시 한번 다듬어서 완성시키고
해당 프롬프트를 Chat GPT4-o, Claude에 넣어 괜찮은 프롬프트인지 확인을 해보면서 완성했습니다.
(CloseSource의 성능을 기준으로 하는 프롬프트지만 진행해 보았습니다.)
comments는 Crawling 한 채팅 데이터입니다.
해당 프롬프트를 기준으로 모델 성능 테스트를 진행하였습니다.
""{comments}
위의 유튜브 라이브 채팅 댓글을 읽고, 주제와 대화의 흐름을 파악하여 아래의 형식으로 **부드럽고 친근한 어조로 존댓말로** 요약해줘:
1. 첫 번째 요약 내용
2. 두 번째 요약 내용
3. 세 번째 요약 내용
요약 예시:
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
긍정:XX/부정:XX
- 위의 형식에 맞춰 요약 내용을 작성해 주고, 흐름을 이해할 수 있을 정도의 구체적인 키워드를 포함해줘.
- **요약 시 부드럽고 자연스러운 표현을 사용해줘.**
- 긍정과 부정의 비율은 전체 100%를 기준으로 계산해줘.
- 다른 불필요한 말은 생략하고, 위의 형식으로만 출력해줘.
"""
3. 환경 설정
HuggingFace모델을 사용하기 위해서는 transformers 라이브러리가 필요합니다.
터미널에서 가상환경 activate를 하고 transformers를 설치할게요.
그리고 저는 후에 hugging face의 API 조건을 device_map으로 auto로 설정해
최대한의 자원을 사용할 예정이므로 accelerate를 설치하겠습니다.
pip install transformers
pip install 'accelerate>=0.26.0'
또한, GPU를 사용하기 위해서 cuda, cudnn을 설치해줍니다.
저는 아래와 같이 설치를 했습니다.
cuda version: 11.8
cudnn version : 9.0.0
Cuda, CuDNN 설치는 아래 포스팅을 참조해주세요.
https://aigaeddo.tistory.com/26
[Tensorflow] 24. tensorflow GPU 가상환경 설정하기
지금까지는 CPU를 이용해서 Tensoflow를 돌렸었는데요, 이번엔 tensorflow에서 gpu를 사용하기 위해 가상환경을 생성하고 세팅해보겠습니다. (먼저 아래 기본적인 개발 세팅이 필요합니다.) https://aigaedd
aigaeddo.tistory.com
버전에 맞는 torch도 설치합니다.
conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
4. 모델 성능 테스트
4-1. gemma-k0-2b 모델
이전 포스팅에서 Crawling한 데이터를 가지고 gemma-k0-2b 모델에 넣어봤습니다.
import torch
import pandas as pd
from transformers import AutoModelForCausalLM, AutoTokenizer
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 모델과 토크나이저 로드
model_name = "beomi/gemma-ko-2b"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map='auto', # Automatically selects the device (GPU)
).to(device)
file_path = './data/jb2f-yxcbRA_chat.csv'
data = pd.read_csv(file_path)
comments = data['댓글 내용'].tolist()
# 사용자 입력에 따른 메시지
prompt = f"""{comments}
위의 유튜브 라이브 채팅 댓글을 읽고, 주제와 대화의 흐름을 파악하여 아래의 형식으로 **부드럽고 친근한 어조로 존댓말로** 요약해줘:
1. 첫 번째 요약 내용
2. 두 번째 요약 내용
3. 세 번째 요약 내용
요약 예시:
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
긍정:XX/부정:XX
- 위의 형식에 맞춰 요약 내용을 작성해 주고, 흐름을 이해할 수 있을 정도의 구체적인 키워드를 포함해줘.
- **요약 시 부드럽고 자연스러운 표현을 사용해줘.**
- 긍정과 부정의 비율은 전체 100%를 기준으로 계산해줘.
- 다른 불필요한 말은 생략하고, 위의 형식으로만 출력해줘.
"""
# 입력 텍스트를 토크나이즈 (여기서는 GPU로 이동할 필요가 없음)
inputs = tokenizer(prompt, return_tensors="pt")
# 모델이 실행되는 GPU로 텐서 전송
inputs = inputs.to(device)
# 텍스트 생성
with torch.no_grad():
output = model.generate(inputs.input_ids, max_length=5000, do_sample=True, temperature=0.7)
# 생성된 텍스트를 디코딩
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print(generated_text)
결과
엥...반복해도 원하는 결과가 나오지 않습니다.
어찌 어색한 답변만 출력됩니다.
- 시간 내에 답변을 완료하지 못하거나 답변이 거창하고 어색하면, 답변 자체를 안 받아줘.
- 그냥 답변을 안 받아주면, 다음에 또 답변을 안 받아주고, 그 다음에도 안 받아주고.
답변:
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
[제안 예시]
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
3-2. ko-gemma-2-9b-it모델
ko-gemma-2-9b-it 모델에서 다시 돌려보겠습니다.
그런데, device_map을 사용하려니 런타임 오류가 납니다.
"RuntimeError: You can't move a model that has some modules offloaded to cpu or disk."
모델이 너무 커서 그렇다고하는데,, 일단 주석처리를 하고 돌려봅니다.
import torch
import pandas as pd
from transformers import AutoModelForCausalLM, AutoTokenizer
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 모델과 토크나이저 로드
model_name = "rtzr/ko-gemma-2-9b-it"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
# device_map='auto', # Automatically selects the device (GPU)
).to(device)
file_path = './data/jb2f-yxcbRA_chat.csv'
data = pd.read_csv(file_path)
comments = data['댓글 내용'].tolist()
# 사용자 입력에 따른 메시지
prompt = f"""{comments}
위의 유튜브 라이브 채팅 댓글을 읽고, 주제와 대화의 흐름을 파악하여 아래의 형식으로 **부드럽고 친근한 어조로 존댓말로** 요약해줘:
1. 첫 번째 요약 내용
2. 두 번째 요약 내용
3. 세 번째 요약 내용
요약 예시:
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
긍정:XX/부정:XX
- 위의 형식에 맞춰 요약 내용을 작성해 주고, 흐름을 이해할 수 있을 정도의 구체적인 키워드를 포함해줘.
- **요약 시 부드럽고 자연스러운 표현을 사용해줘.**
- 긍정과 부정의 비율은 전체 100%를 기준으로 계산해줘.
- 다른 불필요한 말은 생략하고, 위의 형식으로만 출력해줘.
"""
# 입력 텍스트를 토크나이즈 (여기서는 GPU로 이동할 필요가 없음)
inputs = tokenizer(prompt, return_tensors="pt")
# 모델이 실행되는 GPU로 텐서 전송
inputs = inputs.to(device)
# 텍스트 생성
with torch.no_grad():
output = model.generate(inputs.input_ids, max_length=5000, do_sample=True, temperature=0.7)
# 생성된 텍스트를 디코딩
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print(generated_text)
결과
메모리가 터져버렸습니다...
torch.OutOfMemoryError: CUDA out of memory.
Tried to allocate 196.00 MiB. GPU 0 has a total capacity of 23.65 GiB of which 150.31 MiB is free. Process 2596 has 390.70 MiB memory in use.
Including non-PyTorch memory, this process has 22.42 GiB memory in use. Of the allocated memory 22.04 GiB is allocated by PyTorch, and 635.00 KiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)
3-3 ko-gemma-2-9b-it모델 (16bit)
그렇다면 16bit로 변경해서 돌려보겠습니다. 과연 돌아갈 것인지?
torch_dtype=torch.float16
이 한줄로 32bit-> 16bit로 계산을 진행합니다.
부동소수점 축소로 인해 정확성은 떨어질 수 있지만 메모리 사용량이 줄어듭니다.
일단 device_map에서의 Runtime 오류는 발생하지 않았으며
import torch
import pandas as pd
from transformers import AutoModelForCausalLM, AutoTokenizer
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 모델과 토크나이저 로드
model_name = "rtzr/ko-gemma-2-9b-it"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map='auto',
torch_dtype=torch.float16
).to(device)
file_path = './data/jb2f-yxcbRA_chat.csv'
data = pd.read_csv(file_path)
comments = data['댓글 내용'].tolist()
# 사용자 입력에 따른 메시지
prompt = f"""{comments}
위의 유튜브 라이브 채팅 댓글을 읽고, 주제와 대화의 흐름을 파악하여 아래의 형식으로 **부드럽고 친근한 어조로 존댓말로** 요약해줘:
1. 첫 번째 요약 내용
2. 두 번째 요약 내용
3. 세 번째 요약 내용
요약 예시:
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
긍정:XX/부정:XX
- 위의 형식에 맞춰 요약 내용을 작성해 주고, 흐름을 이해할 수 있을 정도의 구체적인 키워드를 포함해줘.
- **요약 시 부드럽고 자연스러운 표현을 사용해줘.**
- 긍정과 부정의 비율은 전체 100%를 기준으로 계산해줘.
- 다른 불필요한 말은 생략하고, 위의 형식으로만 출력해줘.
"""
# 입력 텍스트를 토크나이즈 (여기서는 GPU로 이동할 필요가 없음)
inputs = tokenizer(prompt, return_tensors="pt")
# 모델이 실행되는 GPU로 텐서 전송
inputs = inputs.to(device)
# 텍스트 생성
with torch.no_grad():
output = model.generate(inputs.input_ids, max_length=5000, do_sample=True, temperature=0.7)
# 생성된 텍스트를 디코딩
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print(generated_text)
결과
오.. 메모리도 터지지 않았고, 추구하는 결과가 나오는 모습입니다.
1. 축협 관련 수사에서 홍명보 감독의 해임이 논란이 되었는데, 해당 댓글에서는 축협의 독립성을 존중하며 수사기관의 개입이 어려웠다는 의견과 함께 홍명보 감독 해임 없이 축협에서 경질시키지 않는 한 문제가 해결되지 않을 것이라는 의견이 제시됩니다.
2. 댓글에서는 홍명보 감독을 비판하는 강한 표현과 함께, '야비하게 사익을 쨍기는 몽규놈'과 '돈에 환장한 개보다 못한 인간말종 홍가놈' 등 비난적인 표현과 함께, 험담과 욕설이 섞여 나옵니다.
3. 월드컵 관련 경기 결과와 홍명보 감독의 책임 소재에 대한 의문이 제기되며, 누가 책임을 져야 하는지에 대한 질문과 '명보 응원한다'와 같은 응원 메시지가 나옵니다.
긍정: 20%, 부정: 80%
3-3. Quantizationed ko-gemma-2-9b-it모델
허깅페이스에서는 모델 8bit, 4bit Quantization도 지원합니다.
더욱 메모리를 줄여도 성능이 괜찮을지 실험해보겠습니다.
https://huggingface.co/docs/transformers/main_classes/quantization#transformers.BitsAndBytesConfig
Quantization
Efficient training techniques
huggingface.co
일단 아래의 라이브러리가 필요하니 설치를 해줍니다.
pip install -U bitsandbytes
quantization은 AutoModelForCausalLm의 from_pretrained 메서드의
load_in_8bit , load_in_4bit 를 설정해주면 됩니다.
HuggingFace의 bitsandbytes 라이브러리를 이용한
quantization을 적용하면 from_pretrained.to(device)를 사용하지 못합니다.
자동으로 배치가 되기때문이라고 하네요.
import torch
import pandas as pd
from transformers import AutoModelForCausalLM, AutoTokenizer
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 모델과 토크나이저 로드
model_name = "rtzr/ko-gemma-2-9b-it"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_8bit=True, # 8-bit quantization
#load_in_4bit=True, # 4-bit quantization
device_map='auto',
)
file_path = './data/jb2f-yxcbRA_chat.csv'
data = pd.read_csv(file_path)
comments = data['댓글 내용'].tolist()
# 사용자 입력에 따른 메시지
prompt = f"""{comments}
위의 유튜브 라이브 채팅 댓글을 읽고, 주제와 대화의 흐름을 파악하여 아래의 형식으로 **부드럽고 친근한 어조로 존댓말로** 요약해줘:
1. 첫 번째 요약 내용
2. 두 번째 요약 내용
3. 세 번째 요약 내용
요약 예시:
1. 시청자들은 스트리밍 중 게스트 등장에 신기해 합니다.
2. 시청자들은 스트리머의 시간을 끌고 고민하는 모습이 지루합니다.
3. 시청자들은 게스트들의 대화 내용이 너무 재미있습니다.
긍정:XX/부정:XX
- 위의 형식에 맞춰 요약 내용을 작성해 주고, 흐름을 이해할 수 있을 정도의 구체적인 키워드를 포함해줘.
- **요약 시 부드럽고 자연스러운 표현을 사용해줘.**
- 긍정과 부정의 비율은 전체 100%를 기준으로 계산해줘.
- 다른 불필요한 말은 생략하고, 위의 형식으로만 출력해줘.
"""
# 입력 텍스트를 토크나이즈 (여기서는 GPU로 이동할 필요가 없음)
inputs = tokenizer(prompt, return_tensors="pt")
# 모델이 실행되는 GPU로 텐서 전송
inputs = inputs.to(device)
# 텍스트 생성
with torch.no_grad():
output = model.generate(inputs.input_ids, max_length=5000, do_sample=True, temperature=0.7)
# 생성된 텍스트를 디코딩
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print(generated_text)
8-bit Quantization 결과
1. 축협 독립성과 홍명보 감독 해임 관련 감사 결과를 지적하며, 수사기관의 개입 부재로 인해 축협에서 해임하지 않은 상황에 대해 의문을 표합니다.
2. 홍명보 감독을 비난하며, 비방적인 표현을 사용하여 혐오를 표현하고 있습니다.
3. 축협의 부정부패 의혹을 묻는 질문과, 월드컵과 관련된 책임 추궁과 홍명보 감독 지지를 밝히는 댓글들이 있습니다.
긍정:20%, 부정:80%
4-bit Quantization 결과
1. 축협과 관련된 감사 결과가 나오면서, 일부 시청자들은 홍명보 감독 해임에 대한 의견을 나누고 있습니다.
2. 시청자들은 홍명보 감독과 관련된 문제에 대해 혹독한 비난을 건네고 있습니다.
3. 홍명보 감독에 대한 지지를 표현하는 댓글도 존재합니다.
긍정:20/ 부정:80
테스트 결과
gemma-k0-2b모델은 원하는 성능이 나오지 않았습니다.
ko-gemma-2-9b-it 모델을 추론하는 것은 개발 환경상 불가능 했습니다.
ko-gemma-2-9b-it모델을 16bit로 부동소수점 단위를 변경하면 추론이 가능했으며,
구체적인 요약을 해주었습니다.
ko-gemma-2-9b-it모델을 8-bit, 4-bit로 양자화 한 경우에도 양호한 결과를 도출할 수 있었습니다.
결과적으로는 제가 생각한 프로젝트의 목적이 어느정도의 간략한 요약이므로
어느정도 간략한 요약을 해주면서 메모리 사용량이 비교적 낮은 8-bit Quantization 모델을 사용하기로 결정하였습니다.
5. Summarizer 코드 작성
먼저 필요한 라이브러리를 import 한 후에
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
Summarizer 클래스를 생성해주었습니다.
인스턴스화 시에 HuggingFace 모델을 설정합니다.
이제 해당 클래스는 요약을 담당하는 역할을 맡게 됩니다.
class CommentSummarizer:
def __init__(self):
model_name = "rtzr/ko-gemma-2-9b-it" # 모델 이름
# 모델과 토크나이저 초기화
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_8bit=True, # 8-bit quantization
device_map='auto', # Automatically selects the device (GPU)
)
클래스 내의 메서드입니다.
__extract_sentiment()는 추후 긍정/부정에 대한 데이터가 필요해서 처리하는 메서드입니다.
summarize()는 프롬프트를 전달받아 요약을 진행합니다.
def __extract_sentiment(self, generated_text):
# "긍정:XX/부정:XX" 형식의 데이터 추출
print(generated_text)
# 맨 뒤의 공백 제거
generated_text = generated_text.strip()
positive_ratio = 0
negative_ratio = 0
# 마지막 줄에서 긍정/부정 비율 추출
sentiment_info = generated_text.split("\n")[-1] # 가장 마지막 줄 추출
try:
# 긍정과 부정 비율 추출
if "긍정:" in sentiment_info and "부정:" in sentiment_info:
# 긍정 다음의 숫자 추출
positive_ratio = int(sentiment_info.split("긍정:")[1].split("/")[0].strip().replace('%', ''))
# 부정 다음의 숫자 추출
negative_ratio = int(sentiment_info.split("부정:")[1].strip().replace('%', ''))
except (ValueError, IndexError):
print("긍정 및 부정 비율을 추출하는 데 오류가 발생했습니다.")
return positive_ratio, negative_ratio
def summarize(self, prompt_template, should_stop=None, max_length=500, temperature=0.7):
comments = self.__load_chat()
prompt = prompt_template.format(comments=comments)
input_ids = self.tokenizer.encode(prompt, return_tensors='pt').to(self.device)
prompt_length = input_ids.shape[-1]
# 텍스트 생성 설정
generate_kwargs = {
'input_ids': input_ids,
'max_length': prompt_length + max_length,
'do_sample': True,
'temperature': temperature,
'pad_token_id': self.tokenizer.eos_token_id,
}
# 생성 진행 중에 중단 여부 확인
output = input_ids
try:
with torch.no_grad():
for _ in range(0, max_length, 50): # 50 토큰씩 생성
if should_stop and should_stop():
print("요약 작업 중단됨")
return "요약 작업이 중단되었습니다."
output = self.model.generate(
input_ids=output,
max_length=output.shape[1] + 50,
do_sample=True,
temperature=temperature,
pad_token_id=self.tokenizer.eos_token_id,
eos_token_id=self.tokenizer.eos_token_id,
)
except Exception as e:
print(f"요약 중 에러 발생: {str(e)}")
return f"요약 중 에러 발생: {str(e)}"
generated_tokens = output[0, prompt_length:]
generated_text = self.tokenizer.decode(generated_tokens, skip_special_tokens=True)
# 긍정 및 부정 비율 추출
positive_ratio, negative_ratio = self.extract_sentiment(generated_text)
# 요약 내용과 긍정/부정 비율 반환
return generated_text.strip(), positive_ratio, negative_ratio
전체 코드입니다.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
class CommentSummarizer:
def __init__(self):
model_name = "rtzr/ko-gemma-2-9b-it" # 모델 이름
# 모델과 토크나이저 초기화
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_8bit=True, # 8-bit quantization
device_map='auto', # Automatically selects the device (GPU)
)
self.chat_file_path = None
def summarize(self, prompt_template, should_stop=None, max_length=500, temperature=0.7):
prompt = prompt_template
input_ids = self.tokenizer.encode(prompt, return_tensors='pt').to(self.device)
prompt_length = input_ids.shape[-1]
# 생성 진행 중에 중단 여부 확인
output = input_ids
try:
with torch.no_grad():
for _ in range(0, max_length, 50): # 50 토큰씩 생성
if should_stop and should_stop():
print("요약 작업 중단됨")
return "요약 작업이 중단되었습니다."
output = self.model.generate(
input_ids=output,
max_length=output.shape[1] + 50,
do_sample=True,
temperature=temperature,
pad_token_id=self.tokenizer.eos_token_id,
eos_token_id=self.tokenizer.eos_token_id,
)
except Exception as e:
print(f"요약 중 에러 발생: {str(e)}")
return f"요약 중 에러 발생: {str(e)}"
generated_tokens = output[0, prompt_length:]
generated_text = self.tokenizer.decode(generated_tokens, skip_special_tokens=True)
# 긍정 및 부정 비율 추출
positive_ratio, negative_ratio = self.__extract_sentiment(generated_text)
# 요약 내용과 긍정/부정 비율 반환
return generated_text.strip(), positive_ratio, negative_ratio
def __extract_sentiment(self, generated_text):
# "긍정:XX/부정:XX" 형식의 데이터 추출
print(generated_text)
# 맨 뒤의 공백 제거
generated_text = generated_text.strip()
positive_ratio = 0
negative_ratio = 0
# 마지막 줄에서 긍정/부정 비율 추출
sentiment_info = generated_text.split("\n")[-1] # 가장 마지막 줄 추출
try:
# 긍정과 부정 비율 추출
if "긍정:" in sentiment_info and "부정:" in sentiment_info:
# 긍정 다음의 숫자 추출
positive_ratio = int(sentiment_info.split("긍정:")[1].split("/")[0].strip().replace('%', ''))
# 부정 다음의 숫자 추출
negative_ratio = int(sentiment_info.split("부정:")[1].strip().replace('%', ''))
except (ValueError, IndexError):
print("긍정 및 부정 비율을 추출하는 데 오류가 발생했습니다.")
return positive_ratio, negative_ratio
다음 포스팅에서는 이어서
Flask를 이용한 Web Service 개발 진행 과정에 대해서
포스팅하겠습니다.
#GemmaSprint