SentencePieza es un tokenizador y detokenizador de texto no supervisado principalmente para sistemas de generación de texto basados en redes neuronales donde el tamaño del vocabulario está predeterminado antes del entrenamiento del modelo neuronal. SentencePieza implementa unidades de subpalabras (por ejemplo, codificación de pares de bytes (BPE) [Sennrich et al.]) y modelo de lenguaje unigrama [Kudo.]) con la extensión del entrenamiento directo a partir de oraciones sin procesar. SentencePiece nos permite crear un sistema puramente de un extremo a otro que no depende del procesamiento previo o posterior específico del idioma.
Este no es un producto oficial de Google.
Para aquellos que no están familiarizados con SentencePiece como software/algoritmo, pueden leer una breve introducción aquí.
Característica | FrasePieza | subpalabra-nmt | pieza de palabra |
---|---|---|---|
Algoritmo soportado | BPE, unigrama, char, palabra | BPE | BPE* |
¿OSS? | Sí | Sí | Google interno |
Regularización de subpalabras | Sí | No | No |
Biblioteca de Python (pip) | Sí | No | N / A |
Biblioteca C++ | Sí | No | N / A |
¿Se requiere segmentación previa? | No | Sí | Sí |
Normalización personalizable (por ejemplo, NFKC) | Sí | No | N / A |
Generación de identificación directa | Sí | No | N / A |
Tenga en cuenta que el algoritmo BPE utilizado en WordPiece es ligeramente diferente del BPE original.
SentencePieza es una reimplementación de unidades de subpalabras , una forma eficaz de aliviar los problemas de vocabulario abierto en la traducción automática neuronal. SentencePiece admite dos algoritmos de segmentación, codificación de pares de bytes (BPE) [Sennrich et al.] y modelo de lenguaje unigrama [Kudo.]. Aquí están las diferencias de alto nivel con otras implementaciones.
Los modelos de traducción automática neuronal suelen funcionar con un vocabulario fijo. A diferencia de la mayoría de los algoritmos de segmentación de palabras no supervisados, que asumen un vocabulario infinito, SentencePiece entrena el modelo de segmentación de manera que el tamaño del vocabulario final sea fijo, por ejemplo, 8k, 16k o 32k.
Tenga en cuenta que SentencePiece especifica el tamaño final del vocabulario para el entrenamiento, que es diferente de subword-nmt que utiliza la cantidad de operaciones de fusión. El número de operaciones de fusión es un parámetro específico de BPE y no se aplica a otros algoritmos de segmentación, incluidos unigramas, palabras y caracteres.
Las implementaciones anteriores de subpalabras suponen que las oraciones de entrada están pre-tokenizadas. Esta restricción era necesaria para una capacitación eficiente, pero complica el preprocesamiento ya que tenemos que ejecutar tokenizadores dependientes del idioma por adelantado. La implementación de SentencePiece es lo suficientemente rápida como para entrenar el modelo a partir de oraciones sin procesar. Esto es útil para entrenar el tokenizador y el detokenizador para chino y japonés donde no existen espacios explícitos entre palabras.
El primer paso del procesamiento del lenguaje natural es la tokenización de texto. Por ejemplo, un tokenizador estándar en inglés segmentaría el texto "Hola mundo". en las siguientes tres fichas.
[Hola Mundo] [.]
Una observación es que la entrada original y la secuencia tokenizada NO son reversiblemente convertibles . Por ejemplo, la información que no tiene espacio entre “Mundo” y “.” se elimina de la secuencia tokenizada, ya que, por ejemplo, Tokenize(“World.”) == Tokenize(“World .”)
SentencePieza trata el texto de entrada simplemente como una secuencia de caracteres Unicode. Los espacios en blanco también se tratan como un símbolo normal. Para manejar explícitamente el espacio en blanco como un token básico, SentencePiece primero escapa del espacio en blanco con un metasímbolo " " (U+2581) de la siguiente manera.
Hola mundo.
Luego, este texto se segmenta en pequeños trozos, por ejemplo:
[Hola] [ Wor] [ld] [.]
Dado que el espacio en blanco se conserva en el texto segmentado, podemos detokenizar el texto sin ninguna ambigüedad.
detokenized = ''.join(pieces).replace('▁', ' ')
Esta característica permite realizar la detokenización sin depender de recursos específicos del idioma.
Tenga en cuenta que no podemos aplicar las mismas conversiones sin pérdidas al dividir la oración con segmentadores de palabras estándar, ya que tratan el espacio en blanco como un símbolo especial. Las secuencias tokenizadas no conservan la información necesaria para restaurar la oración original.
La regularización de subpalabras [Kudo.] y el abandono de BPE Provilkov et al son métodos de regularización simples que virtualmente aumentan los datos de entrenamiento con muestreo de subpalabras sobre la marcha, lo que ayuda a mejorar la precisión y la solidez de los modelos NMT.
Para habilitar la regularización de subpalabras, le gustaría integrar la biblioteca SentencePiece (C++/Python) en el sistema NMT para muestrear una segmentación para cada actualización de parámetros, que es diferente de las preparaciones de datos fuera de línea estándar. Aquí está el ejemplo de la biblioteca Python. Puede encontrar que 'Nueva York' está segmentado de manera diferente en cada SampleEncode (C++)
o encode with enable_sampling=True (Python)
. Los detalles de los parámetros de muestreo se encuentran en Sentence_processor.h.
>>> import sentencepiece as spm
>>> s = spm.SentencePieceProcessor(model_file='spm.model')
>>> for n in range(5):
... s.encode('New York', out_type=str, enable_sampling=True, alpha=0.1, nbest_size=-1)
...
['▁', 'N', 'e', 'w', '▁York']
['▁', 'New', '▁York']
['▁', 'New', '▁Y', 'o', 'r', 'k']
['▁', 'New', '▁York']
['▁', 'New', '▁York']
SentencePieza proporciona un contenedor de Python que admite tanto el entrenamiento como la segmentación de SentencePieza. Puede instalar el paquete binario Python de SentencePieza con.
pip install sentencepiece
Para obtener más detalles, consulte el módulo Python.
Se requieren las siguientes herramientas y bibliotecas para crear SentencePiece:
En Ubuntu, las herramientas de compilación se pueden instalar con apt-get:
% sudo apt-get install cmake build-essential pkg-config libgoogle-perftools-dev
Luego, puede crear e instalar herramientas de línea de comandos de la siguiente manera.
% git clone https://github.com/google/sentencepiece.git
% cd sentencepiece
% mkdir build
% cd build
% cmake ..
% make -j $(nproc)
% sudo make install
% sudo ldconfig -v
En OSX/macOS, reemplace el último comando con sudo update_dyld_shared_cache
Puede descargar e instalar oracion usando el administrador de dependencias vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install sentencepiece
Los miembros del equipo de Microsoft y los contribuyentes de la comunidad mantienen actualizado el port de la pieza de oración en vcpkg. Si la versión no está actualizada, cree un problema o una solicitud de extracción en el repositorio de vcpkg.
Puede descargar la rueda desde la página de lanzamientos de GitHub. Generamos firmas SLSA3 utilizando slsa-framework/slsa-github-generator de OpenSSF durante el proceso de lanzamiento. Para verificar un binario de versión:
attestation.intoto.jsonl
desde la página de lanzamientos de GitHub.slsa-verifier -artifact-path < the-wheel > -provenance attestation.intoto.jsonl -source github.com/google/sentencepiece -tag < the-tag >
instalación de pip wheel_file.whl
% spm_train --input=<input> --model_prefix=<model_name> --vocab_size=8000 --character_coverage=1.0 --model_type=<type>
--input
: archivo de corpus sin procesar de una oración por línea. No es necesario ejecutar tokenizador, normalizador o preprocesador. De forma predeterminada, SentencePiece normaliza la entrada con Unicode NFKC. Puede pasar una lista de archivos separados por comas.--model_prefix
: prefijo del nombre del modelo de salida. Se generan <model_name>.model
y <model_name>.vocab
.--vocab_size
: tamaño del vocabulario, por ejemplo, 8000, 16000 o 32000--character_coverage
: cantidad de caracteres cubiertos por el modelo, los buenos valores predeterminados son: 0.9995
para idiomas con un conjunto de caracteres rico como japonés o chino y 1.0
para otros idiomas con un conjunto de caracteres pequeño.--model_type
: tipo de modelo. Elija entre unigram
(predeterminado), bpe
, char
o word
. La oración de entrada debe tener un token previo cuando se usa el tipo word
. Utilice el indicador --help
para mostrar todos los parámetros de entrenamiento, o consulte aquí para obtener una descripción general.
% spm_encode --model=<model_file> --output_format=piece < input > output
% spm_encode --model=<model_file> --output_format=id < input > output
Utilice el indicador --extra_options
para insertar los marcadores BOS/EOS o invertir la secuencia de entrada.
% spm_encode --extra_options=eos (add </s> only)
% spm_encode --extra_options=bos:eos (add <s> and </s>)
% spm_encode --extra_options=reverse:bos:eos (reverse input and add <s> and </s>)
SentencePiece admite la segmentación nbest y el muestreo de segmentación con indicadores --output_format=(nbest|sample)_(piece|id)
.
% spm_encode --model=<model_file> --output_format=sample_piece --nbest_size=-1 --alpha=0.5 < input > output
% spm_encode --model=<model_file> --output_format=nbest_id --nbest_size=10 < input > output
% spm_decode --model=<model_file> --input_format=piece < input > output
% spm_decode --model=<model_file> --input_format=id < input > output
Utilice el indicador --extra_options
para decodificar el texto en orden inverso.
% spm_decode --extra_options=reverse < input > output
% spm_train --input=data/botchan.txt --model_prefix=m --vocab_size=1000
unigram_model_trainer.cc(494) LOG(INFO) Starts training with :
input: "../data/botchan.txt"
... <snip>
unigram_model_trainer.cc(529) LOG(INFO) EM sub_iter=1 size=1100 obj=10.4973 num_tokens=37630 num_tokens/piece=34.2091
trainer_interface.cc(272) LOG(INFO) Saving model: m.model
trainer_interface.cc(281) LOG(INFO) Saving vocabs: m.vocab
% echo "I saw a girl with a telescope." | spm_encode --model=m.model
▁I ▁saw ▁a ▁girl ▁with ▁a ▁ te le s c o pe .
% echo "I saw a girl with a telescope." | spm_encode --model=m.model --output_format=id
9 459 11 939 44 11 4 142 82 8 28 21 132 6
% echo "9 459 11 939 44 11 4 142 82 8 28 21 132 6" | spm_decode --model=m.model --input_format=id
I saw a girl with a telescope.
Puede encontrar que la oración de entrada original se restaura a partir de la secuencia de identificación del vocabulario.
% spm_export_vocab --model=<model_file> --output=<output file>
<output file>
almacena una lista de vocabulario y probabilidades de registros de emisiones. La identificación del vocabulario corresponde al número de línea de este archivo.
Por defecto, la pieza de oración usa tokens desconocidos (), bos (<s>) y eos (</s>) que tienen las ID de 0, 1 y 2 respectivamente. Podemos redefinir este mapeo en la fase de entrenamiento de la siguiente manera.
% spm_train --bos_id=0 --eos_id=1 --unk_id=5 --input=... --model_prefix=... --character_coverage=...
Al configurar -1 id, por ejemplo, bos_id=-1
, este token especial está deshabilitado. Tenga en cuenta que la identificación desconocida no se puede desactivar. Podemos definir una identificación para el relleno (<pad>) como --pad_id=3
.
Si desea asignar otros tokens especiales, consulte Usar símbolos personalizados.
spm_encode
acepta una opción --vocabulary
y --vocabulary_threshold
para que spm_encode
solo produzca símbolos que también aparezcan en el vocabulario (con al menos cierta frecuencia). Los antecedentes de esta función se describen en la página subword-nmt.
El uso es básicamente el mismo que el de subword-nmt
. Suponiendo que L1 y L2 son los dos idiomas (idiomas de origen/destino), entrene el modelo spm compartido y obtenga el vocabulario resultante para cada uno:
% cat {train_file}.L1 {train_file}.L2 | shuffle > train
% spm_train --input=train --model_prefix=spm --vocab_size=8000 --character_coverage=0.9995
% spm_encode --model=spm.model --generate_vocabulary < {train_file}.L1 > {vocab_file}.L1
% spm_encode --model=spm.model --generate_vocabulary < {train_file}.L2 > {vocab_file}.L2
El comando shuffle
se usa por si acaso porque spm_train
carga las primeras 10 millones de líneas del corpus de forma predeterminada.
Luego segmente el corpus de entrenamiento/prueba con la opción --vocabulary
% spm_encode --model=spm.model --vocabulary={vocab_file}.L1 --vocabulary_threshold=50 < {test_file}.L1 > {test_file}.seg.L1
% spm_encode --model=spm.model --vocabulary={vocab_file}.L2 --vocabulary_threshold=50 < {test_file}.L2 > {test_file}.seg.L2