이 프로젝트는 음성 봇과 음성 봇과 상호 작용하기 위한 RESTful 서버라는 두 부분으로 구성됩니다.
봇을 로컬에서 실행하려면 python3 bot.py
(또는 run_bot.sh
)를 실행하고 제안된 메뉴에서 원하는 작업 옵션을 선택해야 합니다(자세한 내용은 여기 참조).
음성 봇 모듈과 상호작용하기 위한 인터페이스를 제공하는 RESTful 서버를 시작하려면 python3 rest_server.py
(또는 run_rest_server.sh
)를 실행해야 합니다(자세한 내용은 여기 참조).
RESTful 서버를 기반으로 Docker 이미지를 빌드하려면 sudo docker build -t voice_chatbot:0.1 .
(자세한 내용은 여기에서).
주목! 이건 내 졸업 프로젝트라서 여기의 아키텍처와 코드가 별로 좋지 않아서 이해하고 시간이 되는 대로 모든 것을 업데이트하겠습니다.
작업에 필요한 모든 종속성의 전체 목록:
Voice_ChatBot_data.zip
(3GB) 아카이브를 수동으로 다운로드하고 프로젝트 루트( data
및 install_files
폴더)에 압축을 풀어야 합니다. Ubuntu 16.04 이상을 사용하는 경우 install_packages.sh
(Ubuntu 16.04 및 18.04에서 테스트됨)를 사용하여 모든 패키지를 설치할 수 있습니다. 기본적으로 CPU용 TensorFlow가 설치됩니다. 공식 드라이버 버전 410이 설치된 nvidia 그래픽 카드가 있는 경우 TensorFlowGPU를 설치할 수 있습니다. 이렇게 하려면 install_packages.sh
실행 시 gpu
매개변수를 전달해야 합니다. 예를 들어:
./install_packages.sh gpu
이 경우 내 Google 드라이브에서 2개의 아카이브가 다운로드됩니다.
Install_CUDA10.0_cuDNN_for410.zip
(2.0Gb)( gpu
매개변수가 전달된 경우) 설치는 자동으로 완료되지만 문제가 발생할 경우 다운로드한 아카이브에 Install.txt
지침이 있습니다.Voice_ChatBot_data.zip
(3Gb). 프로젝트 루트의 data
및 install_files
폴더에 자동으로 압축이 풀립니다. 스크립트를 사용하여 필요한 모든 패키지를 설치할 수 없거나 사용하지 않으려는 경우 install_files/Install RHVoice.txt
및 install_files/Install CMUclmtk.txt
의 지침을 사용하여 RHVoice 및 CMUclmtk_v0.7을 수동으로 설치해야 합니다. 또한 PocketSphinx용 언어, 음향 모델 및 사전 파일을 temp/
에서 /usr/local/lib/python3.6/dist-packages/pocketsphinx/model
로 복사해야 합니다( python3.6
에 대한 경로는 다를 수 있음). 언어 모델 prepared_questions_plays_ru.lm
및 사전 prepared_questions_plays_ru.dic
파일의 이름을 ru_bot_plays_ru.lm
및 ru_bot_plays_ru.dic
로 변경해야 합니다(또는 자체 언어 모델과 사전이 있는 경우 이름을 speech_to_text.py
로 변경해야 합니다).
이 봇은 순환 신경망인 AttentionSeq2Seq 모델을 기반으로 합니다. 현재 구현에서는 인코더의 양방향 LSTM 셀 2개, 주의 계층 1개, 디코더의 LSTM 셀 2개로 구성됩니다. Attention 모델을 사용하면 입력과 출력 시퀀스 간의 "유연한" 대응 관계를 설정할 수 있어 품질과 생산성이 향상됩니다. 마지막 구성의 입력 차원은 500이고 시퀀스 길이는 26입니다(즉, 훈련 세트의 문장의 최대 길이). 단어는 gensim 라이브러리의 word2vec 인코더(445,000 단어 사전 포함)를 사용하여 벡터로 변환됩니다. seq2seq 모델은 Keras와 RecurrentShop을 사용하여 구현됩니다. 소스 파일에 지정된 매개변수를 사용하여 훈련된 seq2seq 모델(가중치는 data/plays_ru/model_weights_plays_ru.h5
에 있음)은 99.19%의 정확도를 갖습니다(즉, 봇은 1601개의 질문 중 1577개의 질문에 정확하게 대답합니다).
현재 봇 훈련을 위한 데이터 세트는 3개입니다. 다양한 연극의 1601개 질문-답변 쌍( data/plays_ru
), 다양한 작품의 136,000 쌍( NLP 데이터 세트 덕분에 data/conversations_ru
), 자막의 2,500,000 쌍 347 TV 시리즈( data/subtitles_ru
, 자세한 내용은 러시아어 자막 데이터세트 참조). word2vec 모델은 모든 데이터 세트에 대해 훈련되지만 신경망은 플레이 세트 데이터 세트에 대해서만 훈련됩니다.
매개변수를 변경하지 않고 연극 데이터 세트에서 word2vec 모델과 신경망을 훈련하는 데는 nvidia gtx1070 및 intel core i7에서 약 7.5시간이 걸립니다. 이 하드웨어의 작품 및 자막 데이터 세트에 대한 교육은 최소 며칠 동안 지속됩니다.
봇은 여러 모드로 작동할 수 있습니다.
훈련 세트는 다양한 러시아 연극에서 가져온 1600개의 질문 %% 답변 쌍으로 구성됩니다. data/plays_ru/plays_ru.txt
파일에 저장됩니다. 각 질문 %% 답변 쌍은 새 줄에 작성됩니다. 한 줄에는 한 쌍만 있습니다.
훈련에 필요한 모든 단계는 text_to_text.py
모듈에 있는 TextToText
클래스의 prepare()
또는 load_prepared()
및 train()
메서드와 preparing_speech_to_text.py
모듈에 있는 LanguageModel
클래스의 build_language_model()
메서드에 의해 수행됩니다. 또는 bot.py
모듈의 train()
함수를 사용할 수 있습니다.
훈련 모드에서 봇을 실행하려면 train
매개변수를 사용하여 bot.py
실행해야 합니다. 예를 들어 다음과 같습니다.
python3 bot.py train
또는 간단히 bot.py
(또는 run_bot.sh
)를 실행하고 제안된 메뉴에서 모드 1과 1을 선택할 수도 있습니다.
학습 과정은 여러 단계로 구성됩니다.
1. 훈련 샘플 준비.
훈련 샘플을 준비하기 위해 SourceToPrepared
클래스로 구성된 source_to_prepared.py
모듈이 사용됩니다. 이 클래스는 파일에서 트레이닝 세트를 읽고, 질문과 답변을 분리하고, 지원되지 않는 문자와 구두점을 제거하고, 결과 질문과 답변을 고정 크기 시퀀스로 변환합니다( <PAD>
필러 단어 사용). 또한 이 수업에서는 네트워크에 대한 질문을 준비하고 응답을 처리합니다. 예를 들어:
입력: "Зачем нужен этот класс? %% Для подготовки данных"
출력: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'подготовки', 'данных', '<EOS>', '<PAD>', ..., '<PAD>']]
훈련 샘플은 data/plays_ru/plays_ru.txt
파일에서 읽혀지고, 변환된 [질문, 답변] 쌍은 data/plays_ru/prepared_plays_ru.pkl
파일에 저장됩니다. 또한, 질문과 답변의 크기에 대한 히스토그램이 생성되어 data/plays_ru/histogram_of_sizes_sentences_plays_ru.png
에 저장됩니다.
연극을 기반으로 한 데이터 세트에서 훈련 샘플을 준비하려면 해당 파일의 이름을 prepare_all()
메서드에 전달하기만 하면 됩니다. 작품이나 자막을 기반으로 한 데이터세트에서 훈련 샘플을 준비하려면 먼저 combine_conversations()
또는 combine_subtitles()
호출한 다음 preapre_all()
호출해야 합니다.
2. 단어를 실제 벡터로 변환합니다.
WordToVec
클래스로 구성된 word_to_vec.py
모듈이 이 단계를 담당합니다. 이 클래스는 고정 크기 시퀀스(즉, 질문과 답변)를 실제 벡터로 인코딩합니다. gensim 라이브러리의 word2vec 인코더가 사용됩니다. 클래스는 훈련 세트의 모든 [질문, 답변] 쌍을 한 번에 벡터로 인코딩하는 방법과 질문을 네트워크에 인코딩하고 해당 답변을 디코딩하는 방법을 구현합니다. 예를 들어:
입력: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'кодирования', 'предложений', '<EOS>', '<PAD>', ..., '<PAD>']]
출력: [[[0.43271607, 0.52814275, 0.6504923, ...], [0.43271607, 0.52814275, 0.6504923, ...], ...], [[0.5464854, 1.01612, 0.15063584, ...], [0.88263285, 0.62758327, 0.6659863, ...], ...]]
(즉, 각 단어는 길이가 500인 벡터로 인코딩됩니다(이 값은 변경 가능, build_word2vec()
메서드의 size
인수))
[질문, 답변] 쌍은 이전 단계에서 얻은 data/plays_ru/prepared_plays_ru.pkl
파일에서 읽습니다. 모델의 품질을 확장하고 향상하려면 자막 data/subtitles_ru/prepared_subtitles_ru.pkl
에서 전처리된 데이터 세트를 추가로 전달하는 것이 좋습니다. data/subtitles_ru/prepared_subtitles_ru.pkl
build_word2vec()
메소드로 변경), 인코딩된 쌍은 data/plays_ru/encoded_plays_ru.npz
파일에 저장됩니다. . 또한 작업 과정에서 사용된 모든 단어의 목록이 작성됩니다. data/plays_ru/w2v_vocabulary_plays_ru.txt
파일에 저장되는 사전입니다. 훈련된 word2vec 모델은 data/plays_ru/w2v_model_plays_ru.bin
에도 저장됩니다.
훈련 세트의 단어를 벡터로 변환하려면 해당 파일의 이름을 build_word2vec()
메서드에 전달하고 원하는 매개변수를 설정하기만 하면 됩니다.
3. 네트워크 훈련.
이 단계에서 seq2seq 모델은 이전에 준비된 데이터를 학습합니다. TextToText
클래스로 구성된 text_to_text.py
모듈이 이를 담당합니다. 이 클래스는 네트워크를 훈련시키고, 네트워크 모델과 가중치 계수를 저장하며, 훈련된 모델과 편리하게 상호 작용할 수 있도록 해줍니다.
학습을 위해서는 이전 단계에서 얻은 벡터로 인코딩된 [질문, 답변] 쌍이 포함된 data/plays_ru/encoded_plays_ru.npz
파일이 필요합니다. 훈련 과정 동안 매 5번째 에포크(이 값은 변경 가능)마다 네트워크 훈련의 최종 중간 결과 data/plays_ru/model_weights_plays_ru_[номер_итерации].h5
파일에 저장되고 마지막 반복에서는 data/plays_ru/model_weights_plays_ru.h5
(반복 - 하나의 네트워크 훈련 주기, 특정 수의 에포크, 그 후 가중치가 파일에 저장되고 예를 들어 네트워크의 정확도를 평가하거나 다른 것을 표시할 수 있습니다. 기본적으로 에포크 수는 5이고, 총 반복 수는 200입니다. 네트워크 모델은 data/plays_ru/model_plays_ru.json
파일에 저장됩니다.
네트워크를 훈련시킨 후 모든 질문을 훈련된 네트워크의 입력에 제출하고 네트워크의 답변을 훈련 세트의 표준 답변과 비교하여 훈련 품질을 평가합니다. 추정 모델의 정확도가 75%보다 높으면 네트워크의 오답이 data/plays_ru/wrong_answers_plays_ru.txt
파일에 저장됩니다(나중에 분석할 수 있도록).
네트워크를 훈련하려면 해당 파일의 이름을 train()
메서드에 전달하고 원하는 매개변수를 설정하기만 하면 됩니다.
4. PocketSphinx용 언어 모델 및 사전 구축.
음성 인식을 사용하려면 이 단계가 필요합니다. 이 단계에서는 훈련 세트의 질문을 기반으로 PocketSphinx용 정적 언어 모델과 음성 사전이 생성됩니다(주의: 훈련 세트에 질문이 많을수록 PocketSphinx가 음성을 인식하는 데 시간이 더 오래 걸립니다). 이렇게 하려면 preparing_speech_to_text.py
모듈에 있는 LanguageModel
클래스의 build_language_model()
메서드(CMUclmtk_v0.7에서 text2wfreq, wfreq2vocab, text2idngram
및 idngram2lm
에 액세스)를 사용하세요. 이 방법은 원래 훈련 세트가 있는 파일의 질문을 사용하고( source_to_prepared.py
모듈에서 준비하기 전) 언어 모델을 temp/prepared_questions_plays_ru.lm
파일에 저장하고 사전을 temp/prepared_questions_plays_ru.dic
( plays_ru
는 어떤 훈련 세트가 사용되었는지에 따라 변경됩니다.) 작업이 끝나면 언어 모델과 사전이 ru_bot_plays_ru.lm
및 ru_bot_plays_ru.dic
이름으로 /usr/local/lib/python3.х/dist-packages/pocketsphinx/model
에 복사됩니다( plays_ru
이전 단계와 마찬가지로 루트 사용자 비밀번호를 입력해야 합니다.)
훈련된 seq2seq 모델과 상호 작용하기 위해 bot.py
모듈의 predict()
함수( text_to_text.py
모듈에 있는 TextToText
클래스의 predict()
메서드에 대한 래퍼)가 사용됩니다. 이 기능은 여러 작동 모드를 지원합니다. 텍스트 모드에서, 즉 사용자가 키보드로 질문을 입력하고 네트워크가 텍스트로 응답하면 text_to_text.py
모듈에 있는 TextToText
클래스의 predict()
메서드만 사용됩니다. 이 메서드는 네트워크에 대한 질문이 포함된 문자열을 받아들이고 네트워크의 응답이 포함된 문자열을 반환합니다. 작업하려면 훈련된 word2vec 모델이 포함된 data/plays_ru/w2v_model_plays_ru.bin
파일, 네트워크 모델의 매개변수가 포함된 data data/plays_ru/model_weights_plays_ru.h5
data/plays_ru/model_plays_ru.json
파일, 그리고 훈련된 네트워크의 가중치.
이 모드에서 봇을 실행하려면 predict
매개변수를 사용하여 bot.py
실행해야 합니다. 예를 들어 다음과 같습니다.
python3 bot.py predict
간단히 bot.py
실행(또는 run_bot.sh
실행)하고 제안된 메뉴에서 모드 2와 1을 선택할 수도 있습니다.
이 모드는 speech_synthesis = True
매개변수가 bot.py
모듈의 predict()
함수에 전달된다는 점에서 이전 모드와 다릅니다. 즉, 네트워크와의 상호 작용은 모드 2와 동일한 방식으로 진행되지만 네트워크의 응답이 추가로 음성으로 표시됩니다.
음성 답변, 즉 text_to_speech.py
모듈에 있는 TextToSpeech
클래스의 get()
메서드에서 구현되는 음성 합성입니다. 이 클래스를 사용하려면 RHVoice-client를 설치해야 하며 명령줄 인수를 사용하여 음성 합성에 필요한 매개변수를 전달합니다( install_files/Install RHVoice.txt
에서 RHVoice 설치 및 RHVoice-client 액세스 예를 볼 수 있습니다). get()
메서드는 음성으로 변환해야 하는 문자열을 입력으로 사용하고, 필요한 경우 합성된 음성이 저장될 .wav 파일의 이름(샘플링 속도는 32kHz, 깊이는 32kHz)을 사용합니다. 16비트, 모노, 지정하지 않으면 합성 직후 음성이 재생됩니다. TextToSpeech
클래스의 개체를 만들 때 사용할 음성 이름을 지정할 수 있습니다. 4가지 음성이 지원됩니다: 남성 Aleksandr와 3명의 여성 – Anna, Elena 및 Irina(자세한 내용은 RHVoice Wiki 참조).
이 모드에서 봇을 실행하려면 predict -ss
매개변수를 사용하여 bot.py
실행해야 합니다. 예를 들어 다음과 같습니다.
python3 bot.py predict -ss
간단히 bot.py
실행(또는 run_bot.sh
실행)하고 제안된 메뉴에서 모드 3과 1을 선택할 수도 있습니다.
이 모드에서 작업하려면 speech_recognition = True
매개변수를 bot.py
모듈의 predict()
함수에 전달해야 합니다. 이는 네트워크와의 상호 작용이나 질문 입력이 음성을 사용하여 수행됨을 의미합니다.
음성 인식은 speech_to_text.py
모듈에 있는 SpeechToText
클래스의 get()
메서드에서 구현됩니다. 이 클래스는 네트워크 훈련 모드에서 구축된 사전( ru_bot_plays_ru.lm
및 ru_bot_plays_ru.dic
)이 있는 PocketSphinx 및 언어 모델을 사용합니다. get()
메서드는 두 가지 모드로 작동할 수 있습니다: from_file
- 샘플링 주파수 >=16kHz, 16비트, 모노(파일 이름이 함수 인수로 전달됨)를 사용하여 .wav 또는 .opus 파일의 음성 인식 및 from_microphone
- 음성 마이크에서 인식. SpeechRecognition
클래스의 인스턴스를 생성할 때 작동 모드가 설정됩니다. 언어 모델을 로드하는 데 시간이 좀 걸립니다(모델이 클수록 로드하는 데 시간이 더 오래 걸립니다).
이 모드에서 봇을 실행하려면 predict -sr
매개변수를 사용하여 bot.py
실행해야 합니다. 예를 들어 다음과 같습니다.
python3 bot.py predict -sr
간단히 bot.py
실행(또는 run_bot.sh
실행)하고 제안된 메뉴에서 모드 4와 1을 선택할 수도 있습니다.
이는 모드 3과 4의 조합입니다.
이 모드에서 작업하려면 speech_recognition = True
및 speech_synthesis = True
매개변수를 bot.py
모듈의 predict()
함수에 전달해야 합니다. 즉, 음성을 사용하여 질문을 입력하고 네트워크 응답을 음성으로 듣게 됩니다. 사용되는 모듈에 대한 설명은 모드 3과 4의 설명에서 확인할 수 있습니다.
이 모드에서 봇을 실행하려면 predict -ss -sr
매개변수를 사용하여 bot.py
실행해야 합니다. 예를 들어 다음과 같습니다.
python3 bot.py predict -sr -ss
또는
python3 bot.py predict -ss -sr
간단히 bot.py
실행(또는 run_bot.sh
실행)하고 제안된 메뉴에서 모드 5와 1을 선택할 수도 있습니다.
이 서버는 봇과 상호 작용하기 위한 REST API를 제공합니다. 서버가 시작되면 연극의 데이터 세트로 훈련된 신경망이 로드됩니다. 작품 및 자막의 데이터 세트는 아직 지원되지 않습니다.
서버는 Flask를 사용하여 구현되고 다중 스레드 모드(프로덕션 버전)는 gevent.pywsgi.WSGIServer를 사용하여 구현됩니다. 또한 서버는 요청 본문의 수신 데이터 크기를 16MB로 제한합니다. 구현은 rest_server.py
모듈에 있습니다.
run_rest_server.sh
실행하여 WSGI 서버를 시작할 수 있습니다( 0.0.0.0:5000
에서 WSGI 서버 시작).
서버는 명령줄 인수를 지원하므로 좀 더 쉽게 시작할 수 있습니다. 인수의 구조는 [ключ(-и)] [адрес:порт]
입니다.
가능한 키:
-d
- 테스트 Flask 서버 시작(키가 지정되지 않으면 WSGI 서버가 시작됩니다)-s
- https 지원으로 서버 시작(openssl을 사용하여 얻은 자체 서명 인증서 사용) 유효한 옵션 адрес:порт
:
host:port
- 지정된 host
및 port
에서 실행localaddr:port
- 로컬 네트워크의 컴퓨터 주소와 지정된 port
자동 감지하여 시작합니다.host:0
또는 localaddr:0
- port = 0
인 경우 사용 가능한 포트가 자동으로 선택됩니다.명령줄 인수와 해당 설명의 가능한 조합 목록:
5000
에서 시스템 주소를 자동 감지하여 WSGI 서버를 시작합니다. 예: python3 rest_server.py
host:port
- 지정된 host
및 port
에서 WSGI 서버를 시작합니다. 예: python3 rest_server.py 192.168.2.102:5000
-d
- 127.0.0.1:5000
에서 테스트 Flask 서버를 시작합니다. 예: python3 rest_server.py -d
-d host:port
- 지정된 host
및 port
에서 테스트 Flask 서버를 시작합니다. 예: python3 rest_server.py -d 192.168.2.102:5000
-d localaddr:port
- 로컬 네트워크 및 포트 port
에서 시스템 주소를 자동 감지하여 테스트 Flask 서버를 시작합니다. 예: python3 rest_server.py -d localaddr:5000
-s
- https 지원, 로컬 네트워크의 컴퓨터 주소 자동 감지 및 포트 5000
사용하여 WSGI 서버를 시작합니다. 예: python3 rest_server.py -s
-s host:port
- 지정된 host
및 port
에서 https를 지원하는 WSGI 서버를 시작합니다. 예: python3 rest_server.py -s 192.168.2.102:5000
-s -d
- 127.0.0.1:5000
에서 https를 지원하는 테스트 Flask 서버를 시작합니다. 예: python3 rest_server.py -s -d
-s -d host:port
- 지정된 host
및 port
에서 https를 지원하는 테스트 Flask 서버를 시작합니다. 예: python3 rest_server.py -s -d 192.168.2.102:5000
-s -d localaddr:port
- https 지원, 로컬 네트워크 및 포트 port
의 컴퓨터 주소 자동 감지를 통해 테스트 Flask 서버를 시작합니다. 예: python3 rest_server.py -s -d localaddr:5000
서버는 사용 가능한 포트 자체를 선택할 수 있습니다. 이를 수행하려면 host:port
또는 localaddr:port
에서 포트 0
지정해야 합니다(예: python3 rest_server.py -d localaddr:0
).
총 5개의 쿼리가 지원됩니다.
/chatbot/about
에 대한 GET 요청은 프로젝트에 대한 정보를 반환합니다./chatbot/questions
에 대한 GET 요청은 지원되는 모든 질문 목록을 반환합니다./chatbot/speech-to-text
에 대한 POST 요청은 .wav/.opus 파일을 수락하고 인식된 문자열을 반환합니다./chatbot/text-to-speech
에 대한 POST 요청은 문자열을 가져와서 합성된 음성이 포함된 .wav 파일을 반환합니다./chatbot/text-to-text
에 대한 POST 요청은 문자열을 수락하고 봇의 응답을 문자열로 반환합니다. 1. 서버에 기본 http 권한이 있습니다. 저것들. 서버에 액세스하려면 base64
(로그인: bot
, 비밀번호: test_bot
)를 사용하여 인코딩된 login:password를 포함하는 각 요청에 헤더를 추가해야 합니다. Python의 예:
import requests
import base64
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
다음과 같이 보일 것입니다:
Authorization: Basic dGVzdGJvdDp0ZXN0
2. 음성 인식 요청(3번)에서 서버는 녹음된 음성이 포함된 .wav 또는 .opus 파일(>=16kHz 16비트 모노)을 기대합니다. 이는 또한 base64
인코딩을 사용하여 json으로 전송됩니다(예: .wav / 열기). .opus 파일, 바이트 배열로 읽은 다음 base64
로 인코딩되고 결과 배열은 바이트 형식에서 문자열로 디코딩됩니다. utf-8
이고 json에 배치됨), Python에서는 다음과 같습니다.
# Формирование запроса
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
with open('test.wav', 'rb') as audio:
data = audio.read()
data = base64.b64encode(data)
data = {'wav' : data.decode()}
# Отправка запроса серверу
r = requests.post('http://' + addr + '/chatbot/speech-to-text', headers=headers, json=data)
# Разбор ответа
data = r.json()
data = data.get('text')
print(data)
3. 음성 합성 요청(4번)에서 서버는 위에서 설명한 대로 인코딩된 합성 음성이 포함된 .wav 파일(16비트 32kHz 모노)이 포함된 json 응답을 보냅니다(다시 디코딩하려면 필요함). 원하는 문자열을 json에서 바이트 배열로 가져온 다음 base64
사용하여 디코딩하고 나중에 재생하기 위해 파일이나 스트림에 씁니다. Python의 예:
# Формирование запроса
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
data = {'text':'который час'}
# Отправка запроса серверу
r = requests.post('http://' + addr + '/chatbot/text-to-speech', headers=headers, json=data)
# Разбор ответа
data = r.json()
data = base64.b64decode(data.get('wav'))
with open('/home/vladislav/Проекты/Voice chat bot/temp/answer.wav', 'wb') as audio:
audio.write(data)
전송된 모든 데이터는 json으로 래핑됩니다(오류가 있는 응답 포함).
{
"text" : "Информация о проекте."
}
{
"text" : ["Вопрос 1",
"Вопрос 2",
"Вопрос 3"]
}
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
또는
{
"opus" : "ZFZm10IBUklQVZFZm10IBARLASBAAEOpH..."
}
서버는 그에게 다음을 보낼 것입니다:
{
"text" : "который час"
}
{
"text" : "который час"
}
서버는 그에게 다음을 보낼 것입니다:
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
{
"text" : "прощай"
}
서버는 그에게 다음을 보낼 것입니다:
{
"text" : "это снова я"
}
1. /chatbot/about
에 대한 GET 요청
python-requests
생성하는 요청의 예:
GET /chatbot/about HTTP/1.1
Host: 192.168.2.83:5000
Connection: keep-alive
Accept-Encoding: gzip, deflate
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: python-requests/2.9.1
컬이 생성하는 요청의 예( curl -v -u testbot:test -i http://192.168.2.83:5000/chatbot/about
):
GET /chatbot/about HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
두 경우 모두 서버가 응답했습니다.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 305
Date: Fri, 02 Nov 2018 15:13:21 GMT
{
"text" : "Информация о проекте."
}
2. /chatbot/questions
에 대한 GET 요청
python-requests
생성하는 요청의 예:
GET /chatbot/questions HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: python-requests/2.9.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
컬이 생성하는 요청의 예( curl -v -u testbot:test -i http://192.168.2.83:5000/chatbot/questions
):
GET /chatbot/questions HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
두 경우 모두 서버가 응답했습니다.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 02 Nov 2018 15:43:06 GMT
{
"text" : ["Что случилось?",
"Срочно нужна твоя помощь.",
"Ты уезжаешь?",
...]
}
3. /chatbot/speech-to-text
에 대한 POST 요청
python-requests
생성하는 요청의 예:
POST /chatbot/speech-to-text HTTP/1.1
Host: 192.168.2.83:5000
User-Agent: python-requests/2.9.1
Accept: */*
Content-Length: 10739
Connection: keep-alive
Content-Type: application/json
Authorization: Basic dGVzdGJvdDp0ZXN0
Accept-Encoding: gzip, deflate
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
컬이 생성하는 요청의 예( curl -v -u testbot:test -i -H "Content-Type: application/json" -X POST -d '{"wav":"UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."}' http://192.168.2.83:5000/chatbot/speech-to-text
):
POST /chatbot/speech-to-text HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 10739
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
서버는 다음과 같이 응답했습니다.
HTTP/1.1 200 OK
Content-Length: 81
Date: Fri, 02 Nov 2018 15:57:13 GMT
Content-Type: application/json
{
"text" : "Распознные слова из аудиозаписи"
}
4. /chatbot/text-to-speech
에 대한 POST 요청
python-requests
생성하는 요청의 예:
POST /chatbot/text-to-speech HTTP/1.1
Host: 192.168.2.83:5000
Connection: keep-alive
Accept: */*
User-Agent: python-requests/2.9.1
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 73
Authorization: Basic dGVzdGJvdDp0ZXN0
{
"text" : "который час"
}
컬이 생성하는 요청의 예( curl -v -u testbot:test -i -H "Content-Type: application/json" -X POST -d '{"text":"который час"}' http://192.168.2.83:5000/chatbot/text-to-speech
):
POST /chatbot/text-to-speech HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 32
{
"text" : "который час"
}
서버는 다음과 같이 응답했습니다.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 78151
Date: Fri, 02 Nov 2018 16:36:02 GMT
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
5. /chatbot/text-to-text
에 대한 POST 요청
python-requests
생성하는 요청의 예:
POST /chatbot/text-to-text HTTP/1.1
Host: 192.168.2.83:5000
Accept-Encoding: gzip, deflate
Content-Type: application/json
User-Agent: python-requests/2.9.1
Connection: keep-alive
Content-Length: 48
Accept: */*
Authorization: Basic dGVzdGJvdDp0ZXN0
{
"text" : "прощай"
}
컬에 의해 생성된 요청의 예( curl -v -u testbot:test -i -H "Content-Type: application/json" -X POST -d '{"text":"прощай"}' http://192.168.2.83:5000/chatbot/text-to-text
):
POST /chatbot/text-to-text HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 23
{
"text" : "прощай"
}
서버는 다음과 같이 응답했습니다.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 68
Date: Fri, 02 Nov 2018 16:41:22 GMT
{
"text" : "это снова я"
}
프로젝트에는 이 프로젝트를 기반으로 Docker 이미지를 빌드할 수 있는 Dockerfile이 포함되어 있습니다. install_packages.sh
사용하여 모든 종속 항목을 설치했고 이전에 Docker를 설치한 적이 없다면 수동으로 설치해야 합니다. 예를 들어 다음과 같습니다(Ubuntu 16.04-18.04에서 테스트됨).
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo apt-add-repository 'deb https://apt.dockerproject.org/repo ubuntu-xenial main' -y
sudo apt-get -y update
sudo apt-get install -y docker-engine
설치 후 sudo systemctl status docker
실행하여 모든 것이 설치되어 작동하는지 확인합니다(이 명령의 출력에서 녹색 텍스트가 active (running)
인 줄을 찾을 수 있습니다).
이미지를 빌드하려면 터미널에서 프로젝트가 있는 폴더로 이동하여 실행해야 합니다. ( -t
- 터미널 실행, .
- docker 빌드가 호출되는 디렉터리(점 - 이는 이미지의 모든 파일이 다음 위치에 있음을 의미) 현재 디렉터리), voice_chatbot:0.1
- 이미지 라벨 및 해당 버전):
sudo docker build -t voice_chatbot:0.1 .
이 작업을 성공적으로 완료한 후 다음을 실행하여 사용 가능한 이미지를 나열할 수 있습니다.
sudo docker images
결과 목록에는 voice_chatbot:0.1
이미지가 표시됩니다.
이제 이 이미지를 실행할 수 있습니다( -t
- 터미널 시작, -i
- 대화형 모드, --rm
- 완료된 후 컨테이너 삭제, -p 5000:5000
- 포트 5000의 모든 연결을 호스트 시스템으로 전달 포트 5000의 컨테이너(외부적으로 연결해야 하는 다른 주소를 명시적으로 지정할 수도 있습니다. 예: -p 127.0.0.1:5000:5000
)):
sudo docker run -ti --rm -p 5000:5000 voice_chatbot:0.1
결과적으로 RESTful 서버는 0.0.0.0:5000
에서 시작되며 터미널에 지정된 주소에서 액세스할 수 있습니다(이미지 시작 시 다른 주소를 지정하지 않은 경우).
참고 : 조립된 도커 이미지의 무게는 5.2GB입니다. 프로젝트의 소스 파일에는 이미지에 추가할 필요가 없는 파일 이름이 포함된 .dockerignore
파일도 포함되어 있습니다. 최종 이미지의 크기를 최소화하기 위해 스토리 및 자막의 데이터 세트와 관련된 모든 파일, 데이터 처리 및 신경망 훈련의 중간 결과가 포함된 파일은 제외되었습니다. 이는 이미지에 학습된 네트워크 파일과 원시 소스 데이터 세트만 포함되어 있음을 의미합니다.
만약을 대비해 프로젝트 소스 파일에는 docker 작업에 필요한 최소한의 명령 세트가 포함된 command_for_docker.txt
파일이 있습니다.
질문이 있거나 협력하고 싶다면 [email protected]이나 LinkedIn을 통해 저에게 편지를 보내주세요.