Gramáticas SRGS

O CPqD ASR permite que as gramáticas para o reconhecimento de fala sejam informadas diretamente no formato de arquivos de texto, seguindo o padrão SRGS.

Os arquivos de gramática podem ser disponibilizados em um diretório local no próprio servidor CPqD ASR, ou através de um servidor WEB, usando HTTP ou HTTPS. Qualquer que seja a forma usada, no momento do reconhecimento, deve-se informar o caminho do arquivo de gramática desejado.

Como exemplo, crie o diretório /opt/grammar/, na máquina do servidor CPqD ASR:

$ sudo mkdir -p /opt/grammar
$ sudo chmod 777 /opt/grammar
$ cd /opt/grammar

Em seguida, crie um arquivo denominado pizza.gram, contendo a seguinte gramática em formato SRGS ABNF:

#ABNF 1.0 UTF-8;
tag-format <semantics/1.0>;
root $pedido;

$pedido = $corpo_pedido [$por_favor] { out = rules.corpo_pedido };

$por_favor = por favor | por gentileza;

$corpo_pedido = [$gostaria] $pizza;

$gostaria = [eu] (quero | queria | gostaria de) [uma];

$pizza = [pizza | de | pizza de] $sabor;

$sabor = calabresa | queijo | vegetariana;

Essa gramática reconhece frases como essas mostradas abaixo:

eu quero pizza de calabresa por gentileza
pizza calabresa por gentileza
pizza vegetariana por favor
queijo
queria calabresa
queria de vegetariana por gentileza
queria pizza queijo
queria pizza vegetariana por gentileza
quero pizza vegetariana por gentileza
vegetariana por gentileza

Em seguida, precisamos de um arquivo de áudio em formato WAV, contendo uma frase como as do exemplo acima, para ser entregue para reconhecimento. O CPqD ASR vem acompanhado de um conjunto de áudios de exemplo, incluindo alguns que podem ser utilizados com a gramática acima. Os arquivos encontram-se no diretório /opt/cpqd/asr/tools/audio/. Vamos utilizar, o arquivo pizza-veg-8k.wav (se o CPqD ASR instalado for para áudio de 16 kHz, utilize o arquivo pizza-veg-16k.wav).

A fim de demonstrar o uso da gramática com o áudio de exemplo, utilizaremos a ferramenta asr-cmd, localizada em /opt/cpqd/asr/tools/engine. Crie um script para a ferramenta asr-cmd, e salve-o como script.txt. O conteúdo do script deve ser o seguinte:

SETENGINE
SETLM file:///opt/grammar/pizza.gram
WAVE /opt/cpqd/asr/tools/audio/pizza-veg-8k.wav
PRINTMODE ALL
RECOGNIZE

A primeira linha do script cria uma instância do motor de reconhecimento. A segunda linha carrega o arquivo de gramática pizza.gram. A terceira linha carrega o arquivo pizza-veg-8k.wav para ser usado no reconhecimento.

Execute a ferramenta asr-cmd passando o script criado:

$ /opt/cpqd/asr/tools/engine/asr-cmd script.txt

Creating engine... (config: /opt/cpqd/asr/config/engine/engine.conf)
 Create engine TIME 2250 ms
 Create session 1 TIME: 0 ms
Setting LM... (URI: file:///opt/grammar/pizza.gram)
 Load LM TIME: 78 ms
Loading wave... (/opt/cpqd/asr/tools/audio/pizza-veg-8k.wav)
Recognizing queued 1 audios...
Recognizing with 1 threads
====================================================================================================
=== TIMESTAMP: Mon Sep 18 17:07:27 2017
=== AUDIO: pizza-veg-8k
=== LM: file:///opt/grammar/pizza.gram
=== LM TIME: 0 ms
=== SEND TIME: 3 ms
=== RECOG TIME: 273 ms
====================================================================================================
= RESULT 1
=   CONFIDENCE: 100
=   INTERPRETATION: "vegetariana" |
=   TEXT: eu  | quero | uma | pizza | vegetariana | por | favor |
=   CONF: 100 |  100  | 100 |  100  |     100     | 100 |  100  |
====================================================================================================
===== THREAD (1/1)
=====   TOTAL LM TIME: 0 ms
=====   TOTAL SEND TIME: 3 ms
=====   TOTAL RECOG TIME: 273 ms
=====   AVERAGE RECOG TIME: 273 ms
====================================================================================================
Finishing...
 Release session (1/1) TIME: 0 ms
 Release engine TIME: 1261 ms

Na saída de exemplo, o resultado do reconhecimento é a frase «eu quero uma pizza vegetariana por favor». Ouça o áudio de entrada e veja que, de fato, essa é a frase dita.

Vamos agora fazer um teste com uma entrada inválida, ou seja, uma sentença fora da gramática. Vamos usar o arquivo pizza-pedra-8k.wav, em que o locutor pede uma pizza de pedra. Altere a terceira linha do arquivo script.txt para apontar para o novo arquivo:

SETENGINE
SETLM file:///opt/grammar/pizza.gram
WAVE /opt/cpqd/asr/tools/audio/pizza-pedra-8k.wav
PRINTMODE ALL
RECOGNIZE

Em seguida, execute novamente a ferramenta asr-cmd:

$ /opt/cpqd/asr/tools/engine/asr-cmd script.txt

Creating engine... (config: /opt/cpqd/asr/config/engine/engine.conf)
 Create engine TIME 2222 ms
 Create session 1 TIME: 0 ms
Setting LM... (URI: file:///opt/grammar/pizza.gram)
 Load LM TIME: 82 ms
Loading wave... (/opt/cpqd/asr/tools/audio/pizza-pedra-8k.wav)
Recognizing queued 1 audios...
Recognizing with 1 threads
====================================================================================================
=== TIMESTAMP: Mon Sep 18 17:12:21 2017
=== AUDIO: pizza-pedra-8k
=== LM: file:///opt/grammar/pizza.gram
=== LM TIME: 0 ms
=== SEND TIME: 3 ms
=== RECOG TIME: 274 ms
====================================================================================================
NO RESULT
====================================================================================================
===== THREAD (1/1)
=====   TOTAL LM TIME: 0 ms
=====   TOTAL SEND TIME: 3 ms
=====   TOTAL RECOG TIME: 274 ms
=====   AVERAGE RECOG TIME: 274 ms
====================================================================================================
Finishing...
 Release session (1/1) TIME: 0 ms
 Release engine TIME: 1273 ms

Desta vez, a ferramenta coloca como saída «NO RESULT», indicando que o áudio não foi reconhecido.

No caso da gramática ser disponibilizada através de servidor WEB, por exemplo na URL http://127.0.0.1/pizza.gram, basta alterar o script para:

SETENGINE
SETLM http://127.0.0.1/pizza.gram
WAVE /opt/cpqd/asr/tools/audio/pizza-pedra-8k.wav
PRINTMODE ALL
RECOGNIZE

O CPqD ASR também aceita gramáticas SRGS em formato XML. Por convenção, tais gramáticas são armazenadas em arquivos com extensão .grxml. Nos exemplos acima, utilizamos a gramática pizza.gram, em formato ABNF; porém, poderíamos ter utilizado a gramática equivalente pizza.grxml, listada abaixo, e obteríamos exatamente os mesmos resultados.

<?xml version="1.0" encoding="utf8" standalone="no" ?>
<grammar xmlns="http://www.w3.org/2001/06/grammar"
         mode="voice"
         root="pedido"
         tag-format="semantics/1.0"
         version="1.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.w3.org/2001/06/grammar http://www.w3.org/TR/speech-grammar/grammar.xsd">

  <rule id="pedido">
    <ruleref uri="#corpo_pedido"/>
    <item repeat="0-1">
      <item>
        <ruleref uri="#por_favor"/>
      </item>
    </item>
    <tag> out = rules.corpo_pedido </tag>
  </rule>

  <rule id="por_favor">
    <one-of>
      <item>por favor</item>
      <item>por gentileza</item>
    </one-of>
  </rule>

  <rule id="corpo_pedido">
    <item repeat="0-1">
      <item>
        <ruleref uri="#gostaria"/>
      </item>
    </item>
    <ruleref uri="#pizza"/>
  </rule>

  <rule id="gostaria">
    <item repeat="0-1">
      <item>eu</item>
    </item>
    <one-of>
      <item>quero</item>
      <item>queria</item>
      <item>gostaria de</item>
    </one-of>
    <item repeat="0-1">
      <item>uma</item>
    </item>
  </rule>

  <rule id="pizza">
    <item repeat="0-1">
      <one-of>
        <item>pizza</item>
        <item>de</item>
        <item>pizza de</item>
      </one-of>
    </item>
    <ruleref uri="#sabor"/>
  </rule>

  <rule id="sabor">
    <one-of>
      <item>calabresa</item>
      <item>queijo</item>
      <item>vegetariana</item>
    </one-of>
  </rule>

</grammar>

Nota

A biblioteca de ASR utiliza a extensão do arquivo no processo de determinar o formato da gramática (ABNF ou XML). Arquivos com extensão .gram são sempre lidos como gramáticas ABNF, e arquivos com extensão .grxml, sempre como gramáticas XML. Se o arquivo de entrada possuir alguma outra extensão, a biblioteca de ASR tentará inferir o formato da gramática pelo seu conteúdo. Porém, é sempre recomendável utilizar a extensão convencional.