Search
moon
sun

챗봇 모델을 해당 과제와 연결

Tags
Date
2024/08/28 → 2024/09/06
URL

🐣 ClovaStudio Test App 이해하기

👱
Clova Studio에서 제공해주는 python code
문제점
해결과정

🌟 따라서, 최종 코드는 아래와 같습니다.

import json import requests class CompletionExecutor: def __init__(self, host, api_key, api_key_primary_val, request_id): self._host = host self._api_key = api_key self._api_key_primary_val = api_key_primary_val self._request_id = request_id def execute(self, completion_request): headers = { 'X-NCP-CLOVASTUDIO-API-KEY': self._api_key, 'X-NCP-APIGW-API-KEY': self._api_key_primary_val, 'X-NCP-CLOVASTUDIO-REQUEST-ID': self._request_id, 'Content-Type': 'application/json; charset=utf-8', 'Accept': 'text/event-stream' } content = "" with requests.post(self._host + '/testapp/v1/tasks/4ce94y7k/chat-completions', headers=headers, json=completion_request, stream=True) as r: for line in r.iter_lines(): if line: decoded_line = line.decode("utf-8") if decoded_line.startswith("data:"): json_data = decoded_line[5:] # 'data:' 이후의 JSON 데이터 추출 try: parsed_data = json.loads(json_data) if 'message' in parsed_data and 'content' in parsed_data['message']: if content == parsed_data['message']['content']: pass else: content += parsed_data['message']['content'] except json.JSONDecodeError: # JSON 형식이 맞지 않을 경우 무시 continue return content if __name__ == '__main__': completion_executor = CompletionExecutor( host='https://clovastudio.stream.ntruss.com', api_key='NTA0MjU2MWZlZTcxNDJiY5OgY4I/+eAv267dQbt+9aDUE0J6DJ/sL2uIey9+AkMG', api_key_primary_val='dn7QeKh9ZQNxR782O4jPEUU02ae6esNz3DhLUsF2', request_id='fc9998a2-5db4-4661-bbfe-887a78a6be7a' ) preset_text = [{"role":"system","content":"당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다\n 당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다. \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 인지 장애인들이 겪는 어려움과 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 다변은 반드시 리스트나 배열에 사용할 수 있도록 다음과 같은 형식으로 출력한다.\n"}] preset_text.append({"role" : "user", "content" : "휠체어를 타고 카페에 가려고 하는데, 추천 경로를 알려줄래?"}) request_data = { 'messages': preset_text, 'topP': 0.8, 'topK': 0, 'maxTokens': 256, 'temperature': 0.5, 'repeatPenalty': 5.0, 'stopBefore': [], 'includeAiFilters': True, 'seed': 0 } # API 호출 및 결과 수집 content = completion_executor.execute(request_data) #print(type(content)) # 최종 content 출력 print(content) <출력 결과> # 참고로 <class 'str'> 입니다. 네! 휠체어를 타고 카페에 가는 추천 경로를 알려드리겠습니다. 1. 지하철 이용 시 엘리베이터가 있는 역을 선택하여 탑승합니다. 2. 목적지 근처 정류장까지 버스를 이용 할 경우 저상버스를 탑승 합니다. 3. 도보 이동 시에는 보도 턱이 낮고 경사로가 있는 곳을 찾아 이동합니다. 4. 카페 입구에 경사로가 있는지 확인 후 입장합니다. 위와 같은 경로를 따라 이동하시면 보다 안전하고 편리하게 카페에 도착하실 수 있습니다. 다만, 도로 상황이나 시설물 상태 등에 따라 경로가 달라질 수 있으므로, 출발 전에 반드시 교통 정보와 시설물 정보를 확인하시기 바랍니다.
Python
복사

🐣 ClovaStudio Test App 응용해보기

👱
이를 이용해서 csv 파일에서 질문 리스트를 불러와서 답변들을 생성하고, 이를 다시 저장하는 방법이 있을까?
🤔
csv 파일에는 질문들의 집합이니깐, for 문을 통해서, 질문 하나씩 추출해서 답변을 불러오면 되지 않을까?
dataset.csv 파일 불러오기
import pandas as pd df = pd.read_csv(r"C:\Users\sook3\OneDrive\바탕 화면\something\학습\DEL 과제\국립재활연구원_2408\chatbot 만들기\datasets.csv") questions_lst = df['Text'] print(questions_lst) <출력 결과> 0 오늘 날짜와 요일을 알려줄 수 있나요? 1 지금 몇 시인지 알고 싶어요. 2 외출해야 하는데 날씨가 어떤가요? 3 마트에 가려는데 근처 마트 위치를 알려주세요. 4 병원에 가야하는데 병원 이름과 전화번호를 알 수 있을까요? ... 71 건강 관리나 체력 유지를 위해 필요한 운동이나 식단 조절 방법을 알려주세요. 72 스트레스나 불안감 해소를 위한 명상이나 요가 등의 방법을 알려주세요. 73 취미 생활이나 여가 활동을 즐길 수 있는 장소나 프로그램을 알려주세요. 74 가족이나 친구들과 소통하고 교류할 수 있는 방법을 알려주세요. 75 안전사고 예방을 위한 대처 방법이나 응급 상황 발생 시 대처 방법을 알려주세요. Name: Text, Length: 76, dtype: object
Python
복사
Try
📎
🤖
우선 아래 부분을 확인해볼까요?
preset_text = [{"role":"system","content":"당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다\n 당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다. \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 인지 장애인들이 겪는 어려움과 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 다변은 반드시 리스트나 배열에 사용할 수 있도록 다음과 같은 형식으로 출력한다.\n"}] preset_text.append({"role" : "user", "content" : "휠체어를 타고 카페에 가려고 하는데, 추천 경로를 알려줄래?"}) request_data = { 'messages': preset_text, 'topP': 0.8, 'topK': 0, 'maxTokens': 256, 'temperature': 0.5, 'repeatPenalty': 5.0, 'stopBefore': [], 'includeAiFilters': True, 'seed': 0 }
Python
복사
이를 응용해보죠.
preset_text = [{"role":"system","content":"당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다\n 당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다. \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 인지 장애인들이 겪는 어려움과 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 다변은 반드시 리스트나 배열에 사용할 수 있도록 다음과 같은 형식으로 출력한다.\n"}] for idx,question in enumerate(question_lst): preset_text.append({"role" : "user", "content" : f"{val}"}) request_data = { 'messages': preset_text, 'topP': 0.8, 'topK': 0, 'maxTokens': 256, 'temperature': 0.5, 'repeatPenalty': 5.0, 'stopBefore': [], 'includeAiFilters': True, 'seed': 0 } content = completion_executor.execute(request_data) print(f"답변 생성 결과 : {content}") print("-------------") df.loc[idx,'Completion'] = content del preset_text[-1] print(df) #df.to_csv("c:/tmp/courses.csv", index=False)
Python
복사
🌟

🌟 최종 코드는 아래와 같습니다.

1.
질문들이 존재하는 dataset들을 pd.read_csv로 불러옵니다.
2.
NaverCLOVA에서 튜닝한 API를 이용해서 답변을 생성합니다.
3.
해당 답변들을 생성하고 dataframe의 column으로 추가해서 datasets.csv파일로 저장합니다.
import json import requests import pandas as pd class CompletionExecutor: def __init__(self, host, api_key, api_key_primary_val, request_id): self._host = host self._api_key = api_key self._api_key_primary_val = api_key_primary_val self._request_id = request_id def execute(self, completion_request): headers = { 'X-NCP-CLOVASTUDIO-API-KEY': self._api_key, 'X-NCP-APIGW-API-KEY': self._api_key_primary_val, 'X-NCP-CLOVASTUDIO-REQUEST-ID': self._request_id, 'Content-Type': 'application/json; charset=utf-8', 'Accept': 'text/event-stream' } content = "" with requests.post(self._host + '/testapp/v1/tasks/4ce94y7k/chat-completions', headers=headers, json=completion_request, stream=True) as r: for line in r.iter_lines(): if line: decoded_line = line.decode("utf-8") if decoded_line.startswith("data:"): json_data = decoded_line[5:] # 'data:' 이후의 JSON 데이터 추출 try: parsed_data = json.loads(json_data) if 'message' in parsed_data and 'content' in parsed_data['message']: if content == parsed_data['message']['content']: pass else: content += parsed_data['message']['content'] except json.JSONDecodeError: # JSON 형식이 맞지 않을 경우 무시 continue return content if __name__ == '__main__': completion_executor = CompletionExecutor( host='https://clovastudio.stream.ntruss.com', api_key='NTA0MjU2MWZlZTcxNDJiY5OgY4I/+eAv267dQbt+9aDUE0J6DJ/sL2uIey9+AkMG', api_key_primary_val='dn7QeKh9ZQNxR782O4jPEUU02ae6esNz3DhLUsF2', request_id='fc9998a2-5db4-4661-bbfe-887a78a6be7a' ) path = r"C:\Users\sook3\OneDrive\바탕 화면\something\학습\DEL 과제\국립재활연구원_2408\chatbot 만들기\datasets.csv" df = pd.read_csv(path) questions_lst = df['Text'] preset_text = [{"role":"system","content":"당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다\n 당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다. \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 인지 장애인들이 겪는 어려움과 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 다변은 반드시 리스트나 배열에 사용할 수 있도록 다음과 같은 형식으로 출력한다.\n"}] for idx,question in enumerate(questions_lst): preset_text.append({"role" : "user","content" : f"{question}"}) request_data = { 'messages': preset_text, 'topP': 0.8, 'topK': 0, 'maxTokens': 256, 'temperature': 0.5, 'repeatPenalty': 5.0, 'stopBefore': [], 'includeAiFilters': True, 'seed': 0 } content = completion_executor.execute(request_data) print(f"답변 생성 결과: {content}") print("----------------------------------") df.loc[idx,'Completion'] = content del preset_text[-1] #print(df) df.to_csv(path, index =False, encoding = "utf-8-sig") # 위에 첨부했습니다.
Python
복사

🐣 MySQL DB와 연결시켜보기

👱
DB로부터 어떠한 상황인지를 LLM에게 브리핑해서 맞춤형으로 대화를 생성하려면?
단순 대화 모델에 상황을 인지시켜서 맞춤형 대화모델이 되는지 테스트해보자.
📖
import json import requests import pandas as pd import mysql.connector import time
Python
복사
DB에서 사용자 정보를 가져오기 위해서 추가한 부분 ( user_id를 입력하면, 해당 정보를 가져오는 함수)
def get_user_info(user_id): connection = mysql.connector.connect( host = 'localhost', user = 'hanshin', password = 'hanshin2024', database = 'users') cur = connection.cursor() cur.execute("SELECT name, disability_type, preferences FROM users WHERE user_id =?",(user_id,)) user_info = cur.fetchone() connection.close() if user_info: return { 'name' : user_info[0], 'disability_type' : user_info[1], 'preferences' : user_info[2] } else: return None
Python
복사
실행 코드에 get_user_info 함수 적용하기
if __name__ == '__main__': completion_executor = CompletionExecutor( host='https://clovastudio.stream.ntruss.com', api_key='NTA0MjU2MWZlZTcxNDJiY5OgY4I/+eAv267dQbt+9aDUE0J6DJ/sL2uIey9+AkMG', api_key_primary_val='dn7QeKh9ZQNxR782O4jPEUU02ae6esNz3DhLUsF2', request_id='fc9998a2-5db4-4661-bbfe-887a78a6be7a' ) path = r"C:\Users\sook3\OneDrive\바탕 화면\something\학습\DEL 과제\국립재활연구원_2408\chatbot 만들기\datasets.csv" df = pd.read_csv(path) questions_lst = df['Text'] # preset_text = [{"role":"system","content":"당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다\n 당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다. \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 인지 장애인들이 겪는 어려움과 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 다변은 반드시 리스트나 배열에 사용할 수 있도록 다음과 같은 형식으로 출력한다.\n"}] for idx,question in enumerate(questions_lst): user_info = get_user_info(user_id = 1) if not user_info: print("User info not found for user_id ") continue preset_text = [{"role":"system", "content" : f"""당신은 {user_info['name']}님을 도와주는 챗봇입니다. {user_info['name']}님은 {user_info['disability_type']}을 가지고 있습니다. 다음 대화에서는 이 정보를 바탕으로 대화하세요.\n - 선호도: {user_info['preferences']} \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 사용자의 disability_type과 관련된 어려움에 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 답변은 반드시 리스트나 배열에 사용할 수 있도록 출력한다.\n - 답변에 사용자의 이름을 불러주는 역할을 추가한다.\n - 답변에 사용자의 선호도를 반영하여 적절한 답변을 생성한다."""} ] preset_text.append({"role" : "user","content" : f"{question}"}) request_data = { 'messages': preset_text, 'topP': 0.8, 'topK': 0, 'maxTokens': 256, 'temperature': 0.5, 'repeatPenalty': 5.0, 'stopBefore': [], 'includeAiFilters': True, 'seed': 0 } content = completion_executor.execute(request_data) print(f"답변 생성 결과: {content}") print("----------------------------------") df.loc[idx,'Completion'] = content time.sleep(1) del preset_text[-1] #print(df) df.to_csv(path, index =False, encoding="utf-8-sig")
Python
복사
<현재는 DB를 생성하지 않았으므로, 아래와 같은 에러가 발생한다.>
--------------------------------------------------------------------------- OperationalError Traceback (most recent call last) Cell In[13], line 16 13 # preset_text = [{"role":"system","content":"당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다\n 당신은 인지에 장애가 있는 장애인들이 일상생활에서 겪는 어려움을 해결해주는 챗봇입니다. \n ### 답변 생성 방법 ### \n - 대화체로 생성한다.\n - 답변은 인지 장애인들이 겪는 어려움과 관련 있게 생성한다.\n - 욕설, 차별적 요소, 부적절한 언어들은 제외한다.\n - 해당 답변은 반드시 리스트나 배열에 사용할 수 있도록 다음과 같은 형식으로 출력한다.\n"}] 15 for idx,question in enumerate(questions_lst): ---> 16 user_info = get_user_info(user_id = 1) 18 if not user_info: 19 print("User info not found for user_id ") Cell In[10], line 5 2 connection = sqlite3.connect('user_data.db') 3 cur = connection.cursor() ----> 5 cur.execute("SELECT name, disability_type, preferences FROM users WHERE user_id =?",(user_id,)) 6 user_info = cur.fetchone() 8 connection.close() OperationalError: no such table: users
👱
그렇다면 실제 user DB를 만들어서 연동시켜보자.
-- 데이터베이스 생성 CREATE DATABASE IF NOT EXISTS user_data; -- 데이터베이스 사용 USE user_data; -- 테이블 생성 CREATE TABLE IF NOT EXISTS users ( user_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, disability_type VARCHAR(100) NOT NULL, preferences TEXT ); -- 샘플 데이터 삽입 INSERT INTO users (name, disability_type, preferences) VALUES ('홍길동', '인지 장애', '시각적 자료 선호'), ('김영희', '청각 장애', '간단한 문장 선호'), ('이철수', '신체 장애', '음성 지원 선호');

🐣 ClovaStudio STT 이해하기

📖
import requests import json class ClovaSpeechClient: # Clova Speech invoke URL invoke_url = 'https://clovaspeech-gw.ncloud.com/external/v1/8983/54d5b161d3da62f82f3592398295d44524110cfef1b81e5ca3dae43e79f634d0' secret = 'b256e2de4b3a4898b3f020894236934f' # 외부 URL을 text로 전환 def req_url(self,url, completion, callback=None, userdata =None, forbiddens=None,boostings=None, wordAlignment=True, fullText=True, diarization=None, sed=None ): request_body = { 'url': url, 'language': 'ko-KR', 'completion': completion, 'callback': callback, 'userdata': userdata, 'wordAlignment': wordAlignment, 'fullText': fullText, 'forbiddens': forbiddens, 'boostings': boostings, 'diarization': diarization, 'sed': sed, } headers = { 'Accept': 'application/json;UTF-8', 'Content-Type': 'application/json;UTF-8', 'X-CLOVASPEECH-API-KEY': self.secret } return requests.post(headers=headers, url=self.invoke_url + '/recognizer/url', data=json.dumps(request_body).encode('UTF-8')) # 클라두으 스토리지에 저장되어 있는 파일을 text로 전환 def req_object_storage(self, data_key, completion, callback=None, userdata=None, forbiddens=None, boostings=None, wordAlignment=True, fullText=True, diarization=None, sed=None): request_body = { 'dataKey': data_key, 'language': 'ko-KR', 'completion': completion, 'callback': callback, 'userdata': userdata, 'wordAlignment': wordAlignment, 'fullText': fullText, 'forbiddens': forbiddens, 'boostings': boostings, 'diarization': diarization, 'sed': sed, } headers = { 'Accept': 'application/json;UTF-8', 'Content-Type': 'application/json;UTF-8', 'X-CLOVASPEECH-API-KEY': self.secret } return requests.post(headers=headers, url=self.invoke_url + '/recognizer/object-storage', data=json.dumps(request_body).encode('UTF-8')) # 로컬 저장소에 있는 파일을 text로 전환 def req_upload(self, file, completion, callback=None, userdata=None, forbiddens=None, boostings=None, wordAlignment=True, fullText=True, diarization=None, sed=None): request_body = { 'language': 'ko-KR', 'completion': completion, 'callback': callback, 'userdata': userdata, 'wordAlignment': wordAlignment, 'fullText': fullText, 'forbiddens': forbiddens, 'boostings': boostings, 'diarization': diarization, 'sed': sed, } headers = { 'Accept': 'application/json;UTF-8', 'X-CLOVASPEECH-API-KEY': self.secret } print(json.dumps(request_body, ensure_ascii=False).encode('UTF-8')) files = { 'media': open(file, 'rb'), 'params': (None, json.dumps(request_body, ensure_ascii=False).encode('UTF-8'), 'application/json') } response = requests.post(headers=headers, url=self.invoke_url + '/recognizer/upload', files=files) return response if __name__ == '__main__': # res = ClovaSpeechClient().req_url(url='http://example.com/media.mp3', completion='sync') # res = ClovaSpeechClient().req_object_storage(data_key='data/media.mp3', completion='sync') """ file에 인식하고자 하는 파일의 경로를 입력하기 """ res = ClovaSpeechClient().req_upload(file='./data/서영은 - 꿈을 꾼다.m4a', completion='sync') print(res.text)
Python
복사
👱
해당 내용은 거의 API처럼 CLOVA에서 제공해주고 있으니, 서영은 - 꿈을 꾼다 노래 파일을 변환해보자.
Terminal 결과
Text 결과
🙂
TTS 성능이라기 보단 음원이라서 성공률이 낮다고 이해해야 하나? 일반 음성으로도 시험을 해보아야겠네. 그래도 생각보다 노래도 잘 변환해주는 것 같아.