Search
moon
sun

240905 νšŒμ˜λ‚΄μš©

✍️
νšŒμ˜λ‚΄μš©
1.
Recording β†’ CSR β†’ chatbot β†’ TTS
a.
μš°μ„  Recording β†’ CSR β†’ chatbot β†’ TTS κΈ°λŠ₯을 κ΅¬ν˜„ν•œ ν›„,
이 κΈ°λŠ₯을 반볡 쑰건을 μ„€μ •ν•˜λŠ” 것을 κ΅¬ν˜„ν•˜κΈ°
b.
Eventκ°€ λ°œμƒν•˜λ©΄, chatbot β†’ TTS κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” κΈ°λŠ₯을 μΆ”κ°€ν•˜κΈ°
β‡’ μœ„ν—˜ 상황 μΈμ§€ν•˜λ©΄, λ°”λ‘œ chatbot이 ν•„μš”ν•œ λŒ€ν™”λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•¨
2.
Dialogue Manager κ°€ 1번 κΈ°λŠ₯을 κ΄€λ¦¬ν•˜λ„λ‘ κ΅¬ν˜„ν•˜κΈ°
3.
Controller classλ₯Ό μƒμ„±ν•˜μ—¬ Clientκ°€ RESTful API μ„œλ²„(Flask)λ₯Ό 톡해 getInfo()처럼 μš”μ²­μ„ ν•˜λ©΄, ν•΄λ‹Ή κΈ°λŠ₯이 μ‹€ν–‰λ˜λ„λ‘ κ΅¬ν˜„ν•΄μ•Ό 함.

πŸ”† μ°Έκ³ 

πŸ’‘Recording

pip install playsound==1.2.2
pip install speech_recognition
pip install pyaudio
# ν•„μš”ν•œ 라이브러리 import import speech_recognition as sr from playsound import playsound import os # Recognizer 객체 생성 r = sr.Recognizer() # 마이크λ₯Ό μ˜€λ””μ˜€ μ†ŒμŠ€λ‘œ μ‚¬μš© mic = sr.Microphone() # μ €μž₯ν•  μ˜€λ””μ˜€ 파일의 이름 folder_name = "./data" file_name = os.path.join(folder_name, "recorded_audio.wav") if not os.path.exists(folder_name): os.makedirs(folder_name) # μŒμ„± λ…ΉμŒ ν•¨μˆ˜ def record_audio(): with mic as source: print("λ…ΉμŒ μ‹œμž‘...") # audio_data = r.listen(source, phrase_time_limit=5) audio_data = r.listen(source) print("λ…ΉμŒ μ™„λ£Œ!") with open(file_name, "wb") as f: f.write(audio_data.get_wav_data()) print("λ…ΉμŒ 파일이 μ €μž₯λ˜μ—ˆμŠ΅λ‹ˆλ‹€.") # μ˜€λ””μ˜€ 파일 μž¬μƒ ν•¨μˆ˜ def play_audio(): playsound(file_name) """ if __name__ == "__main__": # μŒμ„± λ…ΉμŒ audio_data = record_audio() # μ˜€λ””μ˜€ 파일둜 μ €μž₯ with open(file_name, "wb") as f: f.write(audio_data.get_wav_data()) # μ˜€λ””μ˜€ 파일 μž¬μƒ play_audio() """
Python
볡사

πŸ’‘CSR(CLOVA Speech Recognition)

import requests import json
Python
볡사
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
Python
볡사
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/recorded_audio.wav, completion='sync') print(res.text)
Python
볡사

πŸ’‘Chatbot (CLOVA Studio API)

Maria DB둜 λ³€κ²½ν•˜κΈ°
import json import requests import pandas as pd import mysql.connector import time
Python
볡사
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 # completion_request : {"role" : "user","content" : f"{question}"} # POST μš”μ²­μ„ 보내고, μ‹€μ‹œκ°„μœΌλ‘œ 응닡을 μ²˜λ¦¬ν•˜μ—¬ λŒ€ν™” λ‚΄μš©μ„ 생성함 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
Python
볡사
def get_user_info(user_id): connection = mysql.connector.connect( host = 'localhost', user = 'hanshin', password = 'hanshin2024', database = 'user_data') cur = connection.cursor() cur.execute(""" SELECT name, gender, date_of_birth, contact_number, address, photo, disability_types, disability_grade, special_notes FROM users WHERE user_id = %s """, (user_id,)) user_info = cur.fetchone() connection.close() if user_info: return { 'name': user_info[0], 'gender': user_info[1], 'date_of_birth': user_info[2], 'contact_number': user_info[3], 'address': user_info[4], 'photo': user_info[5], # BLOB νƒ€μž…μ΄λ―€λ‘œ μ μ ˆν•œ μ²˜λ¦¬κ°€ ν•„μš”ν•  수 있음 'disability_type': user_info[6], 'disability_grade': user_info[7], 'special_notes': user_info[8] } else: return None
Python
볡사
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 λ§Œλ“€κΈ°\data\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}"}) print(preset_text) 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
볡사

πŸ’‘TTS

πŸ’‘Dialogue_Manager

import record_play import CSR if __name__ == "__main__": # μŒμ„± λ…ΉμŒ audio_data = record_play.record_audio() # μ˜€λ””μ˜€ 파일둜 μ €μž₯ with open(record_play.file_name, "wb") as f: f.write(audio_data.get_wav_data()) # μ˜€λ””μ˜€ 파일 μž¬μƒ record_play.play_audio() res = CSR.ClovaSpeechClient().req_upload(file='./data/recorded_audio.wav', completion='sync') print(res.text)
Python
볡사