该项目由两部分组成 - 语音机器人和用于与其交互的 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 模型。在当前的实现中,它由编码器中的 2 个双向 LSTM 单元、一个注意力层和解码器中的 2 个 LSTM 单元组成。使用注意力模型可以让您在输入和输出序列之间建立“软”对应关系,从而提高质量和生产力。最后一个配置中的输入维度为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 对( data/conversations_ru
,感谢 NLP 数据集)和来自字幕的 2,500,000 对347 部电视剧( data/subtitles_ru
,更多详细信息参见俄语字幕数据集)。 word2vec 模型在所有数据集上进行训练,但神经网络仅在 playsets 数据集上进行训练。
在 nvidia gtx1070 和 intel core i7 上,在不更改参数的情况下在戏剧数据集上训练 word2vec 模型和神经网络大约需要 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 个 epoch(该值可以改变),网络训练的极端中间结果保存在文件data/plays_ru/model_weights_plays_ru_[номер_итерации].h5
中,最后一次迭代时保存在文件data/plays_ru/model_weights_plays_ru.h5
(迭代 - 一个网络训练周期,一定数量的 epoch,之后将权重保存到文件中,例如,您可以评估网络的准确性或显示其他默认情况下,epoch 数为 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
可能根据使用的训练集而变化)。工作结束时,语言模型和字典将被复制到/usr/local/lib/python3.х/dist-packages/pocketsphinx/model
,名称为ru_bot_plays_ru.lm
和ru_bot_plays_ru.dic
( plays_ru
可以在与上一阶段相同,您需要输入root用户密码)。
为了与经过训练的 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/plays_ru/model_plays_ru.json
以及包含网络模型参数的文件data/plays_ru/model_weights_plays_ru.h5
训练后网络的权重。
要在此模式下运行机器人,您需要使用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 文件的名称(采样率为 32 kHz,深度为16 位,单声道;如果未指定,语音将在合成后立即播放)。创建TextToSpeech
类的对象时,您可以指定要使用的语音名称。支持 4 种声音:男性 Aleksandr 和三种女性声音 - 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()
方法中实现的。该课程使用 PocketSphinx 和带有字典的语言模型( ru_bot_plays_ru.lm
和ru_bot_plays_ru.dic
),它们是在网络训练模式下构建的。 get()
方法可以在两种模式下工作: from_file
- 从 .wav 或 .opus 文件中进行语音识别,采样频率 >=16 kHz、16 位、单声道(文件名作为函数参数传递)和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。服务器还对请求正文中接收的数据大小进行限制,即 16 MB。实现在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
。例如: 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
- 启动测试 Flask 服务器,自动检测本地网络上的机器地址和端口port
。例如: python3 rest_server.py -d localaddr:5000
-s
- 启动支持 https 的 WSGI 服务器,自动检测本地网络上的机器地址和端口5000
。例如: 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 的测试 Flask 服务器,自动检测本地网络上的机器地址和端口port
。例如: 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授权。那些。要获得对服务器的访问权限,您需要向每个包含 login:password 的请求添加标头,该标头使用base64
编码(登录名: bot
,密码: test_bot
)。 python 中的示例:
import requests
import base64
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
它看起来像这样:
Authorization: Basic dGVzdGJvdDp0ZXN0
2.在语音识别请求(编号为 3)中,服务器需要一个带有录制语音的 .wav 或 .opus 文件(>=16kHz 16bit mono),该文件也使用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 生成的请求示例 ( 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 生成的请求示例 ( 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. POST 请求到/chatbot/speech-to-text
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 生成的请求示例 ( 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. POST 请求到/chatbot/text-to-speech
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 生成的请求示例 ( 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. POST 请求到/chatbot/text-to-text
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生成的请求示例( 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" : "это снова я"
}
该项目包含一个 Dockerfile,它允许您基于该项目构建 docker 镜像。如果您使用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 build 的目录(点 - 这意味着图像的所有文件都在当前目录), 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
启动,您可以在终端中指定的地址访问它(如果您在启动映像时没有指定其他地址)。
注意:组装后的 docker 镜像大小为 5.2GB。该项目的源文件还包括一个.dockerignore
文件,其中包含不需要添加到映像中的文件的名称。为了最小化最终图像的大小,与故事和字幕数据集相关的所有文件、具有数据处理和神经网络训练中间结果的文件都被排除在外。这意味着图像仅包含经过训练的网络文件和原始源数据集。
以防万一,在项目源文件中有一个command_for_docker.txt
文件,其中包含使用 docker 所需的最少命令集。
如果您有任何疑问或想要合作,可以通过 [email protected] 或 LinkedIn 给我写信。