alphacep / vosk-server

WebSocket, gRPC and WebRTC speech recognition server based on Vosk and Kaldi libraries
Apache License 2.0
868 stars 241 forks source link

Ошибки в asterisk EAGI на большом объеме текста #232

Open epigraphe opened 11 months ago

epigraphe commented 11 months ago

Доброго дня.

Eagi.py взял Ваш https://github.com/alphacep/vosk-server/blob/master/client-samples/asterisk/eagi.py с небольшими дополнениями в виде расстановки препинаков в субпроцессе и отправке результата в телеграмм.

Все настроил, все работает на маленьких объемах. ("Раз-два-три четыре и тому подобное на несколько строк" работает прекрасно, огромное Вам спасибо за поистине титанический труд)

Для теста попробовал наговорить в астериске большой объем текста

Возможности ИИ потрясают. Но заменит ли он человека? Как мы писали выше, в ближайшие 10-20 лет искусственный интеллект по прогнозам захватит треть профессий. Многие уже обеспокоены столь стремительным развитием – например, Илон Маск публично заявил об угрозе ИИ и подписал открытое письмо с призывом приостановить как минимум на полгода обучение систем более мощных, чем языковая модель GPT-4 от OpenAI (правда, месяц спустя он зарегистрировал собственную компанию xAI, которая должна стать конкурентом OpenAI).

Сперва пролетает десятка три ошибок:

file.c:1696 waitstream_core: write() failed: Resource temporarily unavailable

Но при этом весь текст распознается нормально:

 /home/ubuntu/eagi.py: Processing chunk
 /home/ubuntu/eagi.py: Result: {'partial': 'возможности и потрясают но заменит ли он человека как мы писали выше ближайшие десять двадцать лет искусственный интеллект по прогнозам захватят пять профессий многие уже беспокойно столь стремительным развитием например и он маг публично заявил об уг▒       > озе и подписал открытое письмо с призывом приостановить как минимум на'}

Если остановится на небольшом объеме - все происходит, как и расчитывалось.

Если продолжать говорить, то возникает ошибка:

 /home/ubuntu/eagi.py: Processing chunk
[2023-07-28 17:21:52] ERROR[3453][C-00000002]: json.c:607 ast_json_vpack: Error building JSON from '{s: i, s: s}': Invalid UTF-8 string.
[2023-07-28 17:21:52] ERROR[3453][C-00000002]:   Got 11 backtrace records
# 0: /usr/sbin/asterisk(ast_json_pack+0x9d) [0x55ada9fb437d]
# 1: /usr/lib/asterisk/modules/res_agi.so(+0xb638) [0x7f7401bb8638]
# 2: /usr/lib/asterisk/modules/res_agi.so(+0xfee0) [0x7f7401bbcee0]
# 3: /usr/lib/asterisk/modules/res_agi.so(+0x11439) [0x7f7401bbe439]
# 4: /usr/sbin/asterisk(pbx_exec+0xd8) [0x55ada9fe2568]
# 5: /usr/sbin/asterisk(+0x117eb8) [0x55ada9fd6eb8]
# 6: /usr/sbin/asterisk(+0x1198f0) [0x55ada9fd88f0]
# 7: /usr/sbin/asterisk(+0x11ade1) [0x55ada9fd9de1]
# 8: /usr/sbin/asterisk(+0x1923f8) [0x55adaa0513f8]
# 9: /lib/x86_64-linux-gnu/libpthread.so.0(+0x8609) [0x7f7413e75609]
#10: /lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7f7413bf7133]

Затем формируется финальный результат, но не формируется 'text'

/home/ubuntu/eagi.py: Result: {'result': [{'conf': 0.775454, 'end': 5.07, 'start': 4.35, 'word': 'возможности'}, {'conf': 1.0, 'end': 5.46, 'start': 5.07, 'word': 'и'}, {'conf': 0.870522, 'end': 6.15, 'start': 5.46, 'word': ' > ▒отрясают'}, {'conf': 1.0, 'end': 6.27, 'start': 6.15, 'word': 'но'}, {'conf': 0.983217, 'end': 6.63, 'start': 6.27, 'word': 'заменит'}, {'conf': 1.0, 'end': 6.72, 'start': 6.63, 'word': 'ли'}, {'conf': 1.0, 'end': 6.87, 'start': 6.72, 'word': 'он'}, {'conf': 1.0, 'end': 7.44, 'start': 6.87, 'word': 'человека'}, {'conf': 1.0, 'end': 7.62, 'start': 7.44, 'word': 'как'}, {'conf': 1.0, 'end': 7.74, 'start': 7.62, 'word': 'мы'}, {'conf': 1.0, 'end': 8.13, 'start': 7.74, 'word': 'писали'}, {'conf': 1.0, 'end': 8.4, 'start': 8.13, 'word': 'выше'}, {'conf': 0.863426, 'end': 8.429729, 'start': 8.4, 'word': 'в'}, {'conf': 1.0, 'end': 8.85, 'start': 8.429729, 'word': 'ближайшие'}, {'conf': 1.0, 'end': 9.15, 'start': 8.85, 'word': 'десять'}, {'conf': 1.0, 'end': 9.51, 'start': 9.15, 'word': 'двадцать'}, {'conf': 0.978394, 'end': 9.69, 'start': 9.51, 'word': 'лет'}, {'conf': 1.0, 'end': 10.14, 'start': 9.69, 'word': 'искусственный'}, {'conf': 1.0, 'end': 10.470732, 'start': 10.14, 'word': 'интеллект'}, {'conf': 0.839462, 'end': 10.53, 'start': 10.470732, 'word': 'по'}, {'conf': 1.0, 'end': 11.01, 'start': 10.53, 'word': 'прогнозам'}, {'conf': 0.938415, 'end': 11.43, 'start': 11.01, 'word': 'захватят'}, {'conf': 0.657692, 'end': 11.64, 'start': 11.43, 'word': 'треть'}, {'conf': 0.667419, 'end': 12.27, 'start': 11.64, 'word': 'профессий'}, {'conf': 1.0, 'end': 12.72, 'start': 12.33, 'word': 'мн▒ > гие'}, {'conf': 1.0, 'end': 12.93, 'start': 12.72, 'word': 'уже'}, {'conf': 0.655107, 'end': 13.439999, 'start': 12.93, 'word': 'беспокойно'}, {'conf': 1.0, 'end': 13.62, 'start': 13.44, 'word': 'столь'}, {'conf': 1.0, 'end': 14.1, 'start': 13.62, 'word': 'стрем▒

Потом опять ошибки _json.c:607 ast_jsonvpack: Error building JSON from как в примере Выше

Затем идет тонна

[2023-07-28 17:21:52] WARNING[3453][C-00000002]: res_agi.c:3985 parse_args: Too many arguments, truncating
[2023-07-28 17:21:52] WARNING[3453][C-00000002]: res_agi.c:3985 parse_args: Too many arguments, truncating
[2023-07-28 17:21:52] WARNING[3453][C-00000002]: res_agi.c:3985 parse_args: Too many arguments, truncating

И затем вызов завершается

 <SIP/1514-00000001> Playing '/var/lib/asterisk/sounds/ru/custom/beep.slin' (escape_digits=) (sample_offset 0) (language 'ru')
 /home/ubuntu/eagi.py: Traceback (most recent call last):   File /home/ubuntu/eagi.py, line 64, in startAGI     process_chunk(agi, ws, data)   File /home/ubuntu/eagi.py, line 36, in process_chunk     agi.stream_file(/var/lib/asterisk/sounds/ru/custom/beep)   File /usr/local/lib/python3.8/dist-packages/asterisk/agi.py, line 283, in stream_file     response = self.execute(   File /usr/local/lib/python3.8/dist-packages/asterisk/agi.py, line 150, in execute     return self.get_result()   File /usr/local/lib/python3.8/dist-packages/asterisk/agi.py, line 196, in get_result     raise AGIInvalidCommand(response) asterisk.agi.AGIInvalidCommand: Invalid or unknown command
    -- <SIP/1514-00000001>AGI Script /home/ubuntu/eagi.py completed, returning 0
    -- Executing [s@voice-recog:3] Playback("SIP/1514-00000001", "/var/lib/asterisk/sounds/ru/custom/zayavka_ok") in new stack
    -- <SIP/1514-00000001> Playing '/var/lib/asterisk/sounds/ru/custom/zayavka_ok.slin' (language 'ru')
    -- Auto fallthrough, channel 'SIP/1514-00000001' status is 'UNKNOWN'

Подскажите, пожалуйста, с чем это может быть связано? Спасибо

epigraphe commented 11 months ago

В процессе изысканий нашел, что астер пишет вот такую ошибку при выполнении скрипта

os.system("espeak -w /tmp/response22.wav \"" + text.encode('utf-8') + "\"") TypeError: can only concatenate str (not "bytes") to str " 1

nshmyrev commented 11 months ago

Можно удалить encode('utf-8'), это для python2

os.system("espeak -w /tmp/response22.wav \"" + text + "\"")

epigraphe commented 11 months ago

Спасибо.
res_agi.c:3985 parse_args: too many arguments, truncating - пересобрал res_agi c увеличением параметра MAX_ARGS Блок с espeak убрал совсем, логику переделал, теперь озвучивает silero уже после всего.

Ранее распознавание работало так: что-то говоришь, потом пауза и происходило формирование json, который передавался на пунктуацию и далее отрабатывало по ivr.

Теперь распознавание работает таким образом: что-то говоришь, формируется json, текст отправляется, но воск не перестает работать, а снова начинает распознавать.

Есть ли возможность прервать распознавание по нажатию клавиши?

Есть вариант, например, для agi чтобы прервать воспроизведение, но я не могу прикрутить аналогичный вариант для остановки распознавания.

escape_digits = str(“#”)
pressed_digit=agi.stream_file(promptFile,escape_digits)
if pressed_digit == “#”:
sys.exit(0)

То есть, в итоге, я хочу получить продвинутый автоответчик, на который звонящий что-то наговорит, а адресат получит в текстовом виде.

nshmyrev commented 11 months ago

В цикле после или перед

        data = os.read(AUDIO_FD, 8000)

вставляем agi.get_data и проверяем dtmf, если появился, прерываем.

Вообще agi очень неповортливая штука, есть более новый интерфейс ARI:

https://github.com/alphacep/vosk-server/tree/master/client-samples/asterisk-ari

Хотя тоже не идеал. Вообще * бяка.

epigraphe commented 11 months ago

Спасибо, буду пробовать. Изначально хотел на vosk-asterisk, компилил его, но при попытках использования астер падает(

[ 2131.705735] asterisk[11383]: segfault at 0 ip 00007fe1869a1041 sp 00007fe18446b548 error 4 in libc-2.31.so[7fe18683f000+178000]
[ 2131.705754] Code: 01 0f 84 e2 03 00 00 0f 82 cc 03 00 00 49 89 d3 89 f8 31 d2 c5 c5 ef ff 09 f0 25 ff 0f 00 00 3d 80 0f 00 00 0f 8f ef 03 00 00 <c5> fe 6f 0f c5 f5 74 06 c5 fd da c1 c5 fd 74 c7 c5 fd d7 c8 85 c9

Поэтому работаю с этим)

epigraphe commented 11 months ago

Все-таки получилось перекомпилить vost-asterisk, но теперь возникла следующая проблема:

[2023-08-02 10:29:30] NOTICE[11118][C-00000005]: res_speech_vosk.c:81 vosk_recog_create: (vosk) Create speech resource ws://localhost:2700
[2023-08-02 10:29:30] WARNING[11118][C-00000005]: tcptls.c:656 ast_tcptls_client_start_timeout: Unable to connect websocket client to [::1]:2700: Connection refused

Сам сервер работает, тест test.py test.wav проходит. Прямое подключение работает.

python3 -m websockets "ws://localhost:2700"
Connected to ws://localhost:2700.
>

Веб открывается, ожидаемо пишет

Failed to open a WebSocket connection: invalid Connection header: keep-alive.

You cannot access a WebSocket server directly with a browser. You need a WebSocket client.

ufw нет, iptables пустой

iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
[voice-recog]
exten = s,1,Answer
same = n,Wait(1)
same = n,SpeechCreate
same = n,SpeechBackground(hello)
same = n,Verbose(0,Result was ${SPEECH_TEXT(0)})

Подскажите, пожалуйста, что еще можно проверить?

nshmyrev commented 11 months ago

Вместо localhost написать 127.0.0.1 в res_vosk.conf, а то он пытается по ipv6 соединяться.

epigraphe commented 11 months ago

Да, действительно. Затупил на ровном месте. Спасибо Вам большое, все заработало.