Usar un modelo NLP de idioma japonés en Elasticsearch para habilitar búsquedas semánticas

blog-search-results-dark-720x420.png

Encontrar rápido los documentos necesarios entre la gran cantidad de documentos internos e información de productos que se generan a diario es una tarea sumamente importante tanto en el ámbito laboral como en la vida cotidiana. Sin embargo, si hay una gran cantidad de documentos en los cuales buscar, el proceso de volver a leer todos los documentos en tiempo real y encontrar el archivo objetivo puede llevar mucho tiempo, incluso a las computadoras. Esto es lo que llevó a la aparición de Elasticsearch® y demás softwares de motores de búsqueda. Cuando se usa un motor de búsqueda, los datos de índice de búsqueda se crean primero para que los términos de búsqueda clave incluidos en los documentos puedan usarse para encontrar rápidamente esos documentos.

Sin embargo, incluso si el usuario tiene una idea general de qué tipo de información busca, es posible que no pueda recuperar una palabra clave adecuada o puede buscar otra expresión con el mismo significado. Elasticsearch permite que se definan sinónimos y términos similares para tales situaciones; pero en algunas ocasiones, puede resultar difícil usar simplemente una tabla de correspondencia para convertir una consulta de búsqueda en una más adecuada.

Para abordar esta necesidad, Elasticsearch 8.0 lanzó la característica de búsqueda de vectores, que busca por el contenido semántico de una frase. Además, también tenemos una serie de blogs sobre cómo usar Elasticsearch para realizar búsquedas de vectores y otras tareas de NLP. Sin embargo, hasta la versión 8.8, no podía analizar correctamente el texto en otros idiomas que no fueran inglés.

Con la versión 8.9, Elastic agregó la funcionalidad para analizar correctamente el japonés en el procesamiento de análisis de texto. Esta funcionalidad permite a Elasticsearch realizar búsquedas semánticas, como la búsqueda de vectores en texto en japonés, y tareas de procesamiento de lenguaje natural, como el análisis de sentimiento en japonés. En este artículo, brindaremos instrucciones paso a paso específicas sobre cómo usar estas características.

Requisitos previos

Antes de implementar la búsqueda semántica, confirma los requisitos previos para usar esta característica. En los clusters de Elasticsearch, a los roles individuales se les asignan roles de nodos. Mientras tanto, los nodos de machine learning de Elasticsearch son lo que impulsa el modelo de machine learning. Para usar esta característica, debe haber un nodo de machine learning activo en el cluster de Elasticsearch, por lo que debes asegurarte por anticipado de que sea así. También debes tener una licencia Platino o superior para usar los nodos de machine learning. Sin embargo, puedes usar una licencia de prueba si solo deseas probar las características para asegurarte de que funcionen. A fin de verificar la funcionalidad de la operación en un entorno de desarrollo o una instancia similar, activa la prueba en la pantalla de Kibana® o a través de la API.

Proceso de ejecutar una búsqueda semántica

Los pasos siguientes son necesarios para ejecutar una búsqueda semántica en Elasticsearch.

  1. (Preparación) Instala Eland y las bibliotecas relacionadas en la estación de trabajo.

  2. Importa el modelo de machine learning para permitir tareas de procesamiento de lenguaje natural.

  3. Indexa resultados de análisis de texto en el modelo de machine learning importado.

  4. Realiza una búsqueda de kNN usando el modelo de machine learning.

La búsqueda semántica no es lo único que el procesamiento de lenguaje natural habilita. En la segunda mitad de este blog, presentaremos ejemplos de cómo usar el modelo de machine learning, que permite tareas de clasificación de texto, para realizar el análisis de sentimiento de texto (categorías positivas y negativas).

Procedamos a las explicaciones en detalle de cómo realizar las tareas siguientes.

Instalación de Eland

Elasticsearch ahora es capaz de comportarse como una plataforma de procesamiento de lenguaje natural. Sin embargo, la realidad es que ningún procesamiento de lenguaje natural en profundidad se implementa verdaderamente en Elasticsearch. El usuario debe importar cualquier procesamiento de lenguaje natural necesario a Elasticsearch como un modelo de machine learning. Este proceso de importación se realiza con Eland. Dado que los usuarios pueden importar libremente un modelo externo de esta forma, pueden agregar la funcionalidad de machine learning que necesitan cuando sea que la necesiten.

Eland es una biblioteca Python proporcionada por Elastic que permite a los usuarios enlazar los datos de Elasticsearch con bibliotecas de machine learning de Python integrales, como PyTorch and scikit-learn. La herramienta de línea de comando eland_import_hub_model incluida en Eland puede usarse para importar a Elasticsearch modelos de NLP publicados en Hugging Face. Todas las tareas de la línea de comando incluidas a continuación en este artículo suponen que se usa un cuaderno de Python, como Google Colaboratory. (Naturalmente, pueden usarse otro tipo de terminales, como un equipo Mac o Linux. En tales casos, ignora ! al inicio de los comandos siguientes).

Primero, instala bibliotecas dependientes.

!pip install torch==1.13
!pip install transformers
!pip install sentence_transformers
!pip install fugashi
!pip install ipadic
!pip install unidic_lite

Fugashi, ipadic y unidic_lite serán necesarias para usar un modelo de japonés.

Una vez instaladas estas bibliotecas, también se puede instalar Eland. Eland 8.9.0 o posterior será necesario para usar un modelo de japonés, así que asegúrate de prestar atención al número de versión.

!pip install eland

Una vez finalizada la instalación, usa el comando siguiente para confirmar que Eland se pueda usar.

!eland_import_hub_model -h

Importar el modelo NLP

El método principal para habilitar la búsqueda de vectores es el mismo que el usado en inglés en este artículo. Veremos brevemente el mismo procedimiento aquí para repasarlo.

Como explicamos antes, se debe importar el modelo de machine learning apropiado a Elasticsearch para permitir el procesamiento de NLP en Elasticsearch. Puedes implementar un modelo de machine learning tú mismo usando PyTorch, pero esto también requiere experiencia suficiente con machine learning y procesamiento de lenguaje natural, además del poder informático que necesita el machine learning. Sin embargo, ahora existe un repositorio en línea, Hugging Face, muy usado por los investigadores y desarrolladores en los ámbitos de machine learning y procesamiento de lenguaje natural, y muchos modelos se publican en este repositorio. En este ejemplo, usaremos un modelo publicado en Hugging Face para implementar la funcionalidad de búsqueda semántica.

Para comenzar, elijamos un modelo en Hugging Face que incruste (vectorice) oraciones en japonés en vectores numéricos. En este artículo, usaremos el modelo enlazado a continuación.

Veamos algunos puntos a tener en cuenta al seleccionar un modelo de japonés en la versión 8.9.

Primero, solo el algoritmo de modelo BERT tiene soporte. Comprueba las etiquetas en Hugging Face y otra información para confirmar que el modelo NLP deseado es un modelo entrenado BERT.

Además, en el caso de BERT y otras tareas de NLP, el texto que se ingresa se "pretokeniza", lo que significa que el texto se divide en unidades a nivel de la palabra. En este caso, se usa un motor de análisis morfológico del idioma japonés para pretokenizar el texto en japonés. Elasticsearch 8.9 brinda soporte para el análisis morfológico con MeCab. En la página de modelos de Hugging Face, abre la pestaña "Files and versions" (Archivos y versiones) y ve los contenidos del archivo tokenizer_config.json. Confirma que el valor en word_tokenizer_type sea mecab.

{
    "do_lower_case": false,
    "word_tokenizer_type": "mecab",
    "subword_tokenizer_type": "wordpiece",
    "mecab_kwargs": {
        "mecab_dic": "unidic_lite"
    }
}

Desafortunadamente, si el modelo que deseas usar tiene un valor distinto de mecab en word_tokenizer_type, ese modelo no contará con soporte en Elasticsearch en este momento. Agradecemos recibir comentarios sobre cualquier tipo de tokenizador de palabras específico (word_tokenizer_type) para el que se requiera soporte.

Una vez que hayas elegido un modelo para importar, los pasos requeridos para importar son los mismos que para un modelo de inglés. Primero, usa eland_import_hub_model para importar el modelo a Elasticsearch. Consulta esta página para saber cómo usar eland_import_hub_model.

!eland_import_hub_model \
--url "https://your.elasticserach" \
--es-api-key "your_api_key" \
--hub-model-id cl-tohoku/bert-base-japanese-v2 \
--task-type text_embedding \
--start

Una vez que el modelo se haya importado correctamente, se mostrará en Machine Learning > Model Management (Gestión de modelos) > Trained Models (Modelos entrenados) en Kibana. Abre la pestaña "Config" del modelo para ver que "bert_ja" se use para la tokenización y el modelo esté configurado correctamente para japonés.

Configuración de inferencia

Una vez que finalice la carga del modelo, probémoslo. Haz clic en un botón de la columna Actions (Acciones) para abrir el menú.

Acciones

Selecciona "Test model" (Probar modelo), luego ingresa cualquier frase en japonés en "Input text" (Texto de entrada) y haz clic en el botón "Test" (Probar).

Test trained model (Probar modelo entrenado)

Luego podrás ver que el modelo vectorizó el texto en japonés que ingresaste en una cadena numérica, como se muestra aquí. Parece estar funcionando correctamente.

Implementación de búsqueda semántica usando las incrustaciones de vectores

Ahora que el modelo está cargado, podemos implementar la funcionalidad de búsqueda semántica (búsqueda de vectores) en Elasticsearch.

Primero, para realizar una búsqueda de vectores, es necesario indexar los valores de vectores en los que se incrustó el texto en japonés original. Para hacerlo, crearemos un pipeline que incluya un procesador de inferencia para vectorizar el texto en japonés antes de que se ingrese en el índice usando el modelo cargado antes.

PUT _ingest/pipeline/japanese-text-embeddings
{
  "description": "Text embedding pipeline",
  "processors": [
    {
      "inference": {
        "model_id": "cl-tohoku__bert-base-japanese-v2",
        "target_field": "text_embedding",
        "field_map": {
          "title": "text_field"
        }
      }
    }
  ],
  "on_failure": [
    {
      "set": {
        "description": "Index document to 'failed-<index>'",
        "field": "_index",
        "value": "failed-{{{_index}}}"
      }
    },
    {
      "set": {
        "description": "Set error message",
        "field": "ingest.failure",
        "value": "{{_ingest.on_failure_message}}"
      }
    }
  ]
}

Cuando se usa el procesador de inferencia, el modelo especificado en model_id se aplica al texto guardado en el campo de destino (en este caso, title) y la salida se almacena en target_field. Además, cada modelo espera un campo diferente (en este caso, text_field) para el valor de entrada para el proceso. Por ese motivo, field_map se usa para especificar la correspondencia entre el campo de entrada real del objetivo del proceso y el nombre de campo que espera el modelo de ML.

Una vez configurado el pipeline, se puede usar para crear índices. Como se necesitarán campos en esos índices para almacenar vectores, definiremos el mapeo apropiado. En el ejemplo siguiente, el campo text_embedding.predicted_value está configurado para contener datos dense_vector de 768 dimensiones. Ten en cuenta que la cantidad de dimensiones varía según el modelo. Comprueba la página del modelo en Hugging Face (valor hidden_size en el config.json del modelo) o en otro sitio, y configura un número apropiado.

PUT japanese-text-with-embeddings
{
  "mappings": {
    "properties": {
      "text_embedding.predicted_value": {
        "type": "dense_vector",
        "dims": 768,
        "index": true,
        "similarity": "cosine"
      }
    }
  }
}

Si ya hay un índice que incluya los datos de texto en japonés que son el objetivo de la búsqueda, se puede volver a indexar la API. En este ejemplo, los datos de texto originales están en el índice japanese-text. Un documento que contiene la vectorización de ese texto se registra en el índice japanese-text-embeddings.

POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "japanese-text"
  },
  "dest": {
    "index": "japanese-text-with-embeddings",
    "pipeline": "japanese-text-embeddings"
  }
}

Como alternativa, se puede registrar un documento directamente a fin de realizar pruebas especificando un pipeline creado como se muestra a continuación y almacenándolo en el índice.

POST japanese-text-with-embeddings/_doc?pipeline=japanese-text-embeddings
{
  "title": "日本語のドキュメントをベクトル化してインデックスに登録する。"
}

Una vez que el documento vectorizado se registró, finalmente es posible ejecutar una búsqueda. Una búsqueda kNN (k vecino más cercano) es uno de los métodos disponibles que usa vectores. Ahora ejecutaremos una búsqueda de vectores kNN usando la opción query_vector_builder en la API _search estándar. Cuando se usa query_vector_builder, el modelo especificado en model_id puede usarse para convertir el texto en model_text en una búsqueda que contenga un vector en el cual esté incrustado ese texto.

GET japanese-text-with-embeddings/_search
{
  "knn": {
    "field": "text_embedding.predicted_value",
    "k": 10,
    "num_candidates": 100,
    "query_vector_builder": {
      "text_embedding": {
        "model_id": "cl-tohoku__bert-base-japanese-v2", 
        "model_text": "日本語でElasticsearchを検索したい"
      }
    }
  }
}

Cuando se ejecuta esta consulta de búsqueda, se recibe el tipo de respuesta siguiente.

  "hits": [
      {
        "_index": "japanese-text-with-embeddings",
        "_id": "vOD6MIoBdRdLZd7EKaBy",
        "_score": 0.82438844,
        "_source": {
          "title": "日本語のドキュメントをベクトル化してインデックスに登録する。",
          "text_embedding": {
            "predicted_value": [
              -0.13586345314979553,
              -0.6291824579238892,
              0.32779985666275024,
              0.36690405011177063,
              (略、768次元のベクトルが表示される)
            ],
            "model_id": "cl-tohoku__bert-base-japanese-v2"
          }
        }
      }
  ]

¡Búsqueda exitosa! La búsqueda también contiene campos en los que se incrustó japonés. En la mayoría de los casos de uso reales, no es necesario que se incluya este texto en la respuesta. En tales casos, usa _source parameter u otro método para excluir esa información de la respuesta (o tomar otra medida del estilo).

Para ajustar las clasificaciones de búsqueda, se lanzó la característicaReciprocal rank fusion (RRF) (Fusión de rango recíproco [RRF]), que combina hábilmente los resultados de las búsquedas de vectores y las búsquedas de palabras clave estándares. Asegúrate de echarle un vistazo a esto también.

Con esto concluimos nuestro debate sobre cómo habilitar la búsqueda semántica usando la búsqueda de vectores. Si bien configurar esta funcionalidad puede requerir más trabajo que una búsqueda estándar y es posible que encuentres cierto vocabulario exclusivo de machine learning, podrás ejecutar búsquedas casi de modo normal una vez que la fase de configuración esté completa, pruébalo.

Clasificación de texto (análisis de sentimiento)

Como vimos que podemos usar la búsqueda de vectores usando kNN en japonés, veamos cómo usar otras tareas de NLP de la misma forma.

La clasificación de texto es una tarea en la que la entrada de texto se coloca en categorías de algún tipo. Para este ejemplo, usaremos un modelo de análisis de sentimiento encontrado en Hugging Face que juzgue si la entrada de texto en japonés está acompañada de un sentimiento positivo o negativo (koheiduck/bert-japanese-finetuned-sentiment). Si observamos tokenizer_config.json, puede verse que este modelo también usa mecab como word_tokenizer_type, por lo que puede usarse con bert_ja de Elasticsearch.

Como hicimos antes, usa Eland para importar el modelo en Elasticsearch.

!eland_import_hub_model \
--url "https://your.elasticserach" \
--es-api-key "your_api_key" \
--hub-model-id koheiduck/bert-japanese-finetuned-sentiment \
--task-type text_classification \
--start

Una vez que el modelo se haya importado correctamente, se mostrará en Machine Learning > Model Management (Gestión de modelos) > Trained Models (Modelos entrenados) en Kibana.

Configuración de inferencia 2

En este caso, haz clic en "Test model" (Probar modelo) en el menú Actions (Acciones).

Acciones 2

Como antes, esto mostrará un cuadro de diálogo para realizar pruebas. Ingresa aquí el texto para clasificarlo, se clasificará como POSITIVE, NEUTRAL o NEGATIVE. A modo de prueba, ingresemos lo siguiente: "Estoy feliz de poder ejecutar ahora tareas de NLP con Elasticsearch". Como se muestra a continuación, esto generó un resultado 99.2 % positivo.

Modelo 2

A continuación está el mismo proceso ejecutado mediante API.

POST _ml/trained_models/koheiduck__bert-japanese-finetuned-sentiment/_infer
{
  "docs": [{"text_field": "ElasticsearchでNLPのタスクが実行できるようになって嬉しい。"}],
  "inference_config": {
    "text_classification": {
      "num_top_classes": 3
    }
  }
}

La respuesta es la siguiente:

{
  "inference_results": [
    {
      "predicted_value": "POSITIVE",
      "top_classes": [
        {
          "class_name": "POSITIVE",
          "class_probability": 0.9921651090124636,
          "class_score": 0.9921651090124636
        },
        {
          "class_name": "NEUTRAL",
          "class_probability": 0.006682728902566756,
          "class_score": 0.006682728902566756
        },
        {
          "class_name": "NEGATIVE",
          "class_probability": 0.0011521620849697567,
          "class_score": 0.0011521620849697567
        }
      ],
      "prediction_probability": 0.9921651090124636
    }
  ]
}

Como este proceso también puede ejecutarse con el procesador de inferencia, es posible adjuntar estos resultados de análisis antes de que se indexe el texto en japonés. Por ejemplo, aplicar este proceso al texto de comentarios para productos específicos podría ayudar a convertir las valoraciones de los usuarios para dichos productos en valores numéricos.

Comentarios

Hasta Elasticsearch 8.9, el soporte para el modelo NLP de idioma japonés aún está en etapa de vista previa técnica. Comunícate con Elastic® si encuentras errores o necesitas soporte para algoritmos distintos de BERT o tokenizadores distintos de MeCab, etc.

GitHub Issues es la mejor forma de enviar comentarios a Elastic. En "Issues" (Problemas) en el repositorio elastic/elasticsearch, agrega :ml tag y plantea tu solicitud. El equipo indicado lo investigará.

Como arquitecto de consultoría de Elastic (y, por lo tanto, fuera del equipo de desarrollo), pude lograr que agregaran soporte para el idioma japonés enviando una solicitud de incorporación de cambios para una modificación a través de GitHub como colaborador externo. Si eres desarrollador y tienes una característica que te gustaría solicitar que se agregue con un caso de uso específico, inténtalo como yo.

Conclusión

Actualmente, Elastic está invirtiendo muchos recursos en la implementación de la funcionalidad de NLP usando machine learning en sus características de búsqueda, y cada vez hay más tales funciones que pueden ejecutarse en Elasticsearch. Sin embargo, la mayoría de las características se lanzan primero con soporte en inglés y soporte limitado en otros idiomas.

Nos complace que se haya decidido ofrecer soporte para japonés. Esperamos que estas nuevas características de Elasticsearch te ayuden a hacer que las búsquedas sean más significativas.

El lanzamiento y el plazo de cualquier característica o funcionalidad descrita en este blog quedan a la entera discreción de Elastic. Cualquier característica o funcionalidad que no esté disponible actualmente puede no entregarse a tiempo o no entregarse en absoluto.

En este blog, es posible que hayamos usado o mencionado herramientas de AI generativa de terceros, que son propiedad de sus respectivos propietarios y operadas por estos. Elastic no tiene ningún control sobre las herramientas de terceros, y no somos responsables de su contenido, funcionamiento o uso, ni de ninguna pérdida o daño que pueda resultar del uso de dichas herramientas. Ten cautela al usar herramientas de AI con información personal o confidencial. Cualquier dato que envíes puede ser utilizado para el entrenamiento de AI u otros fines. No hay garantías de que la información que proporciones se mantenga segura o confidencial. Deberías familiarizarte con las prácticas de privacidad y los términos de uso de cualquier herramienta de AI generativa previo a su uso.

Elastic, Elasticsearch, ESRE, Elasticsearch Relevance Engine y las marcas asociadas son marcas comerciales, logotipos o marcas comerciales registradas de Elasticsearch N.V. en los Estados Unidos y otros países. Todos los demás nombres de empresas y productos son marcas comerciales, logotipos o marcas comerciales registradas de sus respectivos propietarios.