Genera y administra embeddings de vectores automáticos para tablas grandes

Selecciona una versión de la documentación:

Puedes generar y administrar embeddings de vectores para toda una columna de la tabla, lo que te brinda una solución escalable para la creación de embeddings de vectores a gran escala. Esta solución es particularmente útil para facilitar la búsqueda semántica y la generación mejorada por recuperación (RAG) en el contenido de texto, lo que incluye lo siguiente:

  • Crea un embedding de vector inicial para una tabla nueva
  • Generar embeddings después de una importación de datos grande
  • Actualiza los embeddings después de cambios significativos en los datos
  • Cómo mantener las incorporaciones de forma incremental

Información sobre los embeddings de vectores automáticos

Los embeddings de vectores automáticos en AlloyDB Omni proporcionan una forma escalable de automatizar la generación y el mantenimiento de embeddings de vectores para tus datos. En lugar de generar manualmente embeddings para cada texto nuevo o actualizado, puedes configurar los embeddings de vector automáticos para que se encarguen de este proceso. Esto es especialmente útil para las aplicaciones que dependen de embeddings actualizados para la búsqueda semántica, la generación mejorada por recuperación (RAG) y otras funciones potenciadas por IA.

Con los embeddings de vectores automáticos, puedes hacer lo siguiente:

  • Inicializa los embeddings para una tabla completa: Genera embeddings para todos los datos existentes en una columna de tabla con un solo comando.
  • Mantén las incorporaciones sincronizadas: Actualiza automáticamente las incorporaciones cuando cambien los datos de origen, lo que garantiza que tus aplicaciones de IA siempre funcionen con la información más actual.
  • Genera embeddings a gran escala: Crea embeddings de manera eficiente para tablas grandes con millones de filas.
  • Configura y administra las incorporaciones para varias columnas en la misma tabla llamando a las funciones de administración para cada columna de incorporación.

Esta función simplifica el desarrollo y el mantenimiento de las aplicaciones de IA, ya que abstrae la complejidad de la creación y el mantenimiento de los embeddings de vectores.

Antes de comenzar

Antes de generar y administrar embeddings de vectores para tablas grandes, sigue estos pasos:

  • Verifica y aumenta las cuotas de Vertex AI: Para garantizar un rendimiento óptimo y evitar operaciones lentas, QPS bajas o varios reintentos, verifica y, si es necesario, aumenta tus cuotas de Vertex AI.

    Para verificar y aumentar tus cuotas, sigue estos pasos:

    1. En la consola de Google Cloud , ve a la página Cuotas.
    2. Filtra las siguientes métricas relevantes para tu modelo y región:
      • Para las solicitudes por minuto (RPM): Regional online prediction requests per base model per minute per region per base_model
      • Para los tokens de Gemini: Embed content input tokens per minute per region per base_model
    3. Si los límites actuales no son suficientes para el tamaño de tu tabla, busca el valor de la cuota que deseas actualizar y selecciona la casilla de verificación junto a la cuota.
    4. Haz clic en Editar. Aparecerá el diálogo Cambios de cuota.

      Para obtener más información, consulta Solicita un ajuste de cuota.

    Para conocer los límites del modelo de embeddings de Vertex AI, consulta Límite de tokens del modelo de embeddings de Gemini.

    Para obtener una lista completa de las cuotas, consulta Cuotas y límites de Vertex AI.

  • Conéctate a tu base de datos con psql como el usuario postgres.

  • Verifica que la extensión google_ml_integration esté instalada y que su versión sea 1.5.6 o posterior.

  • Verifica que las marcas google_ml_integration.enable_model_support y google_ml_integration.enable_faster_embedding_generation estén configuradas como on.

  • Antes de generar embeddings desde una base de datos de AlloyDB Omni, debes configurar AlloyDB Omni para que funcione con Vertex AI. Para obtener más información, consulta Integra tu base de datos en Vertex AI.

  • Para administrar y supervisar la generación de la incorporación automática, los usuarios tienen acceso Select a las tablas google_ml.embed_gen_progress y google_ml.embed_gen_settings de forma predeterminada.

    Para permitir que un usuario administre la generación de la incorporación automática, otorga los permisos INSERT, UPDATE y DELETE en las tablas google_ml.embed_gen_progress y google_ml.embed_gen_settings:

    GRANT INSERT, UPDATE, DELETE ON google_ml.embed_gen_progress TO 'USER_NAME';
    

    Reemplaza lo siguiente:

    • USER_NAME: Es el nombre del usuario al que se le otorgan los permisos.
  • Finaliza la configuración inicial que se describe en Genera embeddings de texto.

  • Verifica que AUTOCOMMIT esté configurado como ON en el cliente de PostgreSQL que usas.

Verifica la versión de la extensión

Para verificar la versión de la extensión google_ml_integration, ejecuta el siguiente comando:

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';

Si necesitas actualizar la extensión, ejecuta el siguiente comando:

ALTER EXTENSION google_ml_integration UPDATE;

Verifica que las marcas de la base de datos estén configuradas en on.

Para verificar que las marcas de la base de datos estén configuradas correctamente, ejecuta los siguientes comandos:

SHOW google_ml_integration.enable_model_support;
SHOW google_ml_integration.enable_faster_embedding_generation;

Si estas marcas están configuradas como off, consulta Configura las marcas de base de datos de una instancia. Para obtener más información sobre estas marcas, consulta Marcas de base de datos compatibles.

Prepara la mesa

Antes de generar embeddings automáticos, debes crear una columna en tu tabla para almacenar los vectores resultantes. Por lo general, esta columna usa el tipo vector(DIMENSION) y debe tener un valor DEFAULT NULL.

Por ejemplo, para agregar una columna para embeddings de 768 dimensiones a una tabla llamada user_reviews, haz lo siguiente:

ALTER TABLE user_reviews ADD COLUMN IF NOT EXISTS content_embeddings vector(768) DEFAULT NULL;

Inicializa embeddings para una tabla

Las funciones para administrar las incorporaciones de vectores automáticas están disponibles en los esquemas ai y google_ml. El esquema ai proporciona una interfaz simplificada para las funciones potenciadas por IA más recientes en AlloyDB Omni.

Usa la función ai.initialize_embeddings() de SQL para generar embeddings para la columna de contenido de una tabla. Esta es una llamada de bloqueo, lo que significa que la sesión de la base de datos espera a que se complete la operación antes de devolver un resultado y permitirte emitir comandos nuevos en esa sesión. Sin embargo, no se bloquean otras conexiones a la base de datos y pueden seguir trabajando con la tabla:

  • Si la función devuelve un valor de éxito, se completó la creación del embedding de vector.
  • La función intenta recuperarse automáticamente de problemas transitorios, como errores de cuota del modelo. Solo se te devolverá un error si estos intentos de recuperación no tienen éxito. En el caso de problemas persistentes, como un batch_size mal configurado que hace que la solicitud supere los límites de tamaño, o si la operación se canceló de forma manual, debes volver a emitir la llamada de forma manual.

Esta función admite modelos proporcionados por Google (por ejemplo, text-embedding-005 de Vertex AI), así como modelos personalizados que hayas registrado.

Realiza la generación por lotes

De forma predeterminada, AlloyDB Omni usa el procesamiento por lotes para generar embeddings para varias entradas de texto en una sola solicitud, lo que mejora la eficiencia. Si no proporcionas un tamaño de lote específico, AlloyDB Omni aplica un valor predeterminado determinado automáticamente.

Tamaño de lote de sugerencias

El parámetro batch_size en ai.initialize_embeddings te permite guiar al optimizador de consultas de AlloyDB Omni sugiriendo un tamaño de lote preferido para los modelos admitidos directamente. AlloyDB Omni podría reducir dinámicamente este tamaño según los límites o las cuotas del modelo, pero tu sugerencia ayuda a influir en el plan de ejecución de la consulta.

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'user_reviews',
    content_column => 'content',
    embedding_column => 'content_embeddings',
    batch_size => 50
);

Usa un modelo de incorporación personalizado con compatibilidad para lotes

Si deseas usar un modelo personalizado o compatible de forma externa que admita el procesamiento por lotes, define las funciones de transformación por lotes y especifícalas como model_batch_in_transform_fn y model_batch_out_transform_fn cuando crees un modelo. También puedes especificar un batch_size en la llamada a initialize_embeddings. En el caso de los modelos que admiten el procesamiento por lotes, te recomendamos que uses un batch_size mayor que 1 para obtener un mejor rendimiento.

  1. Define las funciones de entrada, salida y transformación por lotes de tu modelo personalizado.

    -- Scalar input transform functions
    CREATE OR REPLACE FUNCTION acme_text_input_transform(model_id TEXT, input TEXT) RETURNS JSON;
    CREATE OR REPLACE FUNCTION acme_text_output_transform(model_id TEXT, model_output JSON) RETURNS real[];
    CREATE OR REPLACE FUNCTION acme_generate_headers(model_id TEXT, input TEXT) RETURNS JSON;
    -- Batch input transform functions
    CREATE OR REPLACE FUNCTION acme_text_batch_input_transform(model_id TEXT, input TEXT[]) RETURNS JSON;
    CREATE OR REPLACE FUNCTION acme_text_batch_output_transform(model_id TEXT, model_output JSON) RETURNS real[][];
    
  2. Para crear tu modelo, especifica las funciones de transformación por lotes.

    CALL
      ai.create_model(
        model_id => 'custom-embedding-model',
        model_request_url => 'https://acme.com/models/text/embeddings/v1',
        model_type => 'text_embedding',
        model_in_transform_fn => 'acme_text_input_transform',
        model_out_transform_fn => 'acme_text_output_transform',
        generate_headers_fn => 'acme_generate_headers',
        model_batch_in_transform_fn => 'acme_text_batch_input_transform',
        model_batch_out_transform_fn => 'acme_text_batch_output_transform'
      );
    
  3. Genera embeddings de vectores con tu modelo personalizado.

    CALL
      ai.initialize_embeddings(
        model_id => 'custom-embedding-model',
        table_name => 'user_reviews',
        content_column => 'content',
        embedding_column => 'content_embeddings',
        batch_size => 10
    );
    

También puedes usar la función de incorporación automática con modelos personalizados que no admiten de forma nativa el procesamiento por lotes. Para ello, debes definir las funciones de transformación por lotes model_batch_in_transform_fn y model_batch_out_transform_fn. Para un modelo que no procesa por lotes, define estas funciones para procesar una sola entrada a la vez desde el array de entrada. Cuando llames a ai.initialize_embeddings para este modelo, establece batch_size en 1.

Usa la dimensionalidad personalizada con compatibilidad por lotes

Para usar una función de transformación de entrada por lotes personalizada con el parámetro OUTPUT_DIMENSIONALITY, puedes definir una función que especifique las dimensiones seleccionadas en los parámetros de la solicitud. Esto es útil para optimizar la generación de embeddings para modelos que admiten tamaños de salida variables.

Por ejemplo, la siguiente función define una transformación de entrada por lotes personalizada para un modelo que requiere una dimensionalidad de salida de 768:

CREATE OR REPLACE FUNCTION google_ml.vertexai_text_embedding_batch_input_transform_with_768_dims(model_id VARCHAR(100), input_list TEXT[])
RETURNS JSON
LANGUAGE SQL
AS $$
  SELECT pg_catalog.json_build_object(
    'instances',
    pg_catalog.json_agg(pg_catalog.json_build_object('content', content)),
    'parameters',
    pg_catalog.json_build_object('outputDimensionality', 768)
  ) FROM unnest(input_list) AS content;
$$;

Usa la optimización de JSONB con modelos personalizados

Puedes usar el tipo de datos JSONB en tus funciones de transformación de salida personalizadas para mejorar el rendimiento. Cuando creas un modelo personalizado con compatibilidad con lotes, la extensión google_ml_integration busca y usa automáticamente una variante JSONB de tus funciones de transformación.

Esta optimización puede mejorar significativamente el rendimiento de la generación automática de incorporaciones, ya que JSONB es un formato binario más eficiente para almacenar y procesar datos JSON en PostgreSQL.

Para aprovechar esta función, debes proporcionar otra versión de tu función de transformación que acepte un argumento JSONB en lugar de JSON.

Por ejemplo, si tienes una función de transformación de salida por lotes con la siguiente firma:

CREATE OR REPLACE FUNCTION my_batch_output_transform(model_id TEXT, model_output JSON) RETURNS real[][];

Puedes crear una variante de JSONB de la siguiente manera:

CREATE OR REPLACE FUNCTION my_batch_output_transform(model_id TEXT, model_output JSONB) RETURNS real[][];

La extensión detecta automáticamente la presencia de la versión JSONB de la función y la usa para el procesamiento por lotes. Si ya creaste un registro de modelo que usa una función de transformación JSON, no es necesario que actualices tu llamada a ai.create_model. Siempre y cuando la nueva función JSONB use exactamente el mismo nombre que la función JSON existente, la extensión detectará y usará de forma transparente la variante JSONB para el procesamiento por lotes.

Actualiza las incorporaciones de forma incremental

Cuando actualizas una incorporación, se vuelve a generar según el valor más reciente de la columna de contenido de entrada.

Para brindarte control sobre la coherencia y el rendimiento, AlloyDB Omni admite varios modos para las actualizaciones incrementales de la incorporación. Puedes seleccionar un modo con el argumento de enumeración incremental_refresh_mode en ai.initialize_embeddings(). A continuación, se incluye una lista de los modos posibles:

  • transactional: Las incorporaciones se actualizan como parte de la transacción que actualiza la columna de contenido. Este proceso, que a menudo usa un mecanismo similar a un activador de base de datos para generar automáticamente incorporaciones cuando se actualiza la columna de contenido, puede generar una sobrecarga y ralentizar las operaciones de actualización. La sobrecarga introducida es una compensación para mantener la semántica transaccional y garantizar que las incorporaciones estén sincronizadas con el contenido. Este modo se basa en las funciones de transformación escalar de tu modelo, por lo que debes definir model_in_transform_fn y model_out_transform_fn cuando crees el modelo. Para usar el modo transactional, debes tener el rol de propietario en la tabla.

    CALL
      ai.initialize_embeddings(
        model_id => 'text-embedding-005',
        table_name => 'user_reviews',
        content_column => 'content',
        embedding_column => 'content_embeddings',
        batch_size => 10,
        incremental_refresh_mode => 'transactional'
    );
    

    En el modo transactional, la función ai.refresh_embeddings() está inhabilitada porque las incorporaciones se mantienen sincronizadas automáticamente con activadores. Para volver a generar las incorporaciones de toda la tabla o recuperarte de una llamada a ai.initialize_embeddings() interrumpida en este modo, primero debes descartar la configuración con la función ai.drop_embedding_config() y, luego, volver a emitir la llamada a ai.initialize_embeddings().

    Este modo automatizado es útil para demostraciones, conjuntos de datos pequeños o tablas en las que el volumen de inserciones y actualizaciones es bajo en comparación con la carga inicial, por ejemplo, unas pocas cientos de actualizaciones diarias en una tabla de un millón de filas. Es adecuado cuando mantener la coherencia de los datos inmediatos es más importante que la latencia adicional que se introduce durante las operaciones de actualización.

  • manual: Este es el modo predeterminado. En este modo, se agrega una nueva columna de seguimiento booleana a tu tabla para hacer un seguimiento de los embeddings obsoletos. Llamar a la función ai.refresh_embeddings() realiza una actualización incremental periódica, ya que solo genera incorporaciones para las filas nuevas o actualizadas. Recomendamos este modo para los usuarios que requieren más control sobre el rendimiento, en especial cuando se maneja una gran cantidad de inserciones o actualizaciones después de la carga inicial. Es útil en situaciones en las que minimizar la latencia de escritura es una prioridad y en las que se acepta tener incorporaciones nulas o desactualizadas temporalmente hasta que se active una actualización incremental periódica con ai.refresh_embeddings. Para actualizar filas obsoletas o nuevas, usa la función ai.refresh_embeddings() como se describe en la sección Actualiza todas las incorporaciones de una tabla.

Elige un modo de actualización

En la siguiente tabla, se comparan los dos modos de actualización incremental para ayudarte a elegir el mejor enfoque para tu aplicación.

Modo Descripción Coherencia y rendimiento Ideal para
transactional Las incorporaciones se actualizan como parte de la transacción de la base de datos con un mecanismo similar a un activador. Ten en cuenta que ai.refresh_embeddings() está inhabilitado en este modo. Coherencia inmediata. Sobrecarga de latencia de escritura alta, ya que cada INSERT o UPDATE activa una generación de incorporación. Demos, conjuntos de datos pequeños o tablas en las que la coherencia de los datos es fundamental
manual (predeterminada) Usa una columna de seguimiento booleana para supervisar las filas nuevas o desactualizadas. Debes llamar a ai.refresh_embeddings() para activar una actualización incremental periódica. Coherencia eventual. Latencia de escritura mínima, ya que las incorporaciones se generan de forma masiva en el momento que elijas. Conjuntos de datos grandes, entornos de producción con alta frecuencia de escritura o aplicaciones sensibles al rendimiento

Actualiza todos los embeddings de una tabla

Después de ejecutar ai.initialize_embeddings() correctamente para una tabla con el modo de actualización incremental manual, puedes realizar una actualización incremental periódica de tus incorporaciones, que se activa con ai.refresh_embeddings. Puedes usar una operación de actualización para actualizar las incorporaciones de las filas que se modifican de forma simultánea durante la llamada inicial a initialize_embeddings o para realizar una actualización incremental periódica.

Si el proceso de creación de la incorporación se interrumpe en el modo manual, por ejemplo, con pg_cancel, llama a la función ai.refresh_embeddings() para completar la generación de las filas restantes.

La función de actualización reutiliza la configuración de la llamada inicial, por lo que solo debes especificar la tabla y la columna de incorporación. También puedes proporcionar un batch_size opcional para anular el valor predeterminado.

CALL ai.refresh_embeddings(
    table_name => 'user_reviews',
    embedding_column => 'content_embeddings',
    batch_size => 50  -- Optional override
);

Trabaja con datos de tablas durante la creación de embeddings de vectores

Si bien ai.initialize_embeddings() es una llamada de bloqueo para la sesión en la que se ejecuta, otras conexiones pueden seguir trabajando con la tabla. El proceso de embedding de vector automático actualiza las filas en lotes con el bloqueo estándar a nivel de la fila. Esto significa que las operaciones simultáneas del lenguaje de modificación de datos (DML), como UPDATE o DELETE, de otras conexiones solo se bloquean brevemente si intentan modificar las mismas filas a las que apunta la tarea de incorporación activa. Las consultas de SELECT que no modifican datos no se bloquean.

Borra la configuración de los embeddings de vectores automáticos

Si necesitas quitar la configuración de embedding de vector automático para una combinación específica de tabla y columna de embedding, usa la función ai.drop_embedding_config(). Esta función puede ser útil para la limpieza o cuando vuelves a configurar la administración de la incorporación para una columna.

CALL
  ai.drop_embedding_config(
    table_name => 'user_reviews',
    embedding_column => 'content_embeddings');

Trabaja con tablas particionadas

La función de embedding de vectores automático admite tablas particionadas. Esto te permite administrar incorporaciones para conjuntos de datos grandes y particionados de manera eficiente. Estos son los casos de uso comunes para trabajar con tablas particionadas.

Inicializa embeddings en una tabla particionada

Solo puedes inicializar embeddings en la partición raíz de una tabla. Esta es una operación única para toda la tabla particionada.

CALL ai.initialize_embeddings(
    model_id => 'text-embeddings-005',
    table_name => 'documents', -- This is the root partitioned table
    content_column => 'content',
    embedding_column => 'content_embeddings'
);

Actualiza los embeddings en una tabla particionada

Después de la inicialización, puedes actualizar las incorporaciones en cualquier partición, incluida la partición raíz, las subparticiones o las particiones de hoja individuales. En el caso de los conjuntos de datos grandes, puedes mejorar el rendimiento actualizando las incorporaciones de particiones distintas en paralelo desde diferentes conexiones de bases de datos:

  • Para actualizar toda la tabla, ejecuta el siguiente comando:
CALL ai.refresh_embeddings(
    table_name => 'documents', -- This is the root partitioned table
    embedding_column => 'content_embeddings'
);
  • Para actualizar una sola partición, ejecuta el siguiente comando:
CALL ai.refresh_embeddings(
    table_name => 'documents_eu',
    embedding_column => 'content_embeddings'
);

Actualiza las incorporaciones para las particiones adjuntas o agregadas recientemente

La función de incorporación automática admite la generación de incorporaciones para las particiones que se incorporan a tu tabla principal después de la configuración inicial. Los pasos específicos dependen de si agregas una partición completamente nueva o adjuntas una tabla preexistente.

  • Partición agregada recientemente: Si agregas una partición nueva a la tabla, puedes generar incorporaciones para ella llamando a ai.refresh_embeddings en la partición nueva.
-- Add a new partition
CREATE TABLE documents_africa PARTITION OF documents
    FOR VALUES IN ('africa');

-- Refresh embeddings for the new partition
CALL ai.refresh_embeddings(
    table_name => 'documents_africa',
    embedding_column => 'content_embeddings'
);
  • Partición adjunta recientemente: Para adjuntar una tabla existente como partición, primero usa el procedimiento ai.embedding_prepare_partition para asegurarte de que su esquema sea compatible con la tabla particionada. La función de incorporación automática admite la adición o la vinculación de particiones en cualquier nivel de una configuración de particiones jerárquica. El procedimiento ai.embedding_prepare_partition garantiza que el esquema sea compatible con cualquier tabla principal de la jerarquía.

Para adjuntar una tabla existente como partición, primero usa el procedimiento ai.embedding_prepare_partition para asegurarte de que su esquema sea compatible con la tabla particionada:

-- Prepare the table to be attached
CALL ai.embedding_prepare_partition(
    parent_table => 'documents',
    child_table => 'documents_misc'
);

-- Attach the partition
ALTER TABLE documents ATTACH partition documents_misc DEFAULT;

-- Refresh embeddings for the newly attached partition
CALL ai.refresh_embeddings(
    table_name => 'documents_misc',
    embedding_column => 'content_embeddings'
);

La función de incorporación automática admite la adición o la vinculación de particiones en cualquier nivel de una configuración de particiones jerárquica. El procedimiento ai.embedding_prepare_partition garantiza que el esquema sea compatible con cualquier tabla principal de la jerarquía:

-- Prepare a sub-partition for a non-root parent table
CALL ai.embedding_prepare_partition(
    parent_table => 'documents_eu', -- An existing partition
    child_table => 'documents_eu_germany'
);

-- Attach the new sub-partition
ALTER TABLE documents_eu ATTACH PARTITION documents_eu_germany
    FOR VALUES IN ('germany');

-- Refresh embeddings for the new sub-partition
CALL ai.refresh_embeddings(
    table_name => 'documents_eu_germany',
    embedding_column => 'content_embeddings'
);

Supervisa el progreso de la generación de embeddings

Puedes supervisar el estado en tiempo real de las llamadas initialize_embeddings y refresh_embeddings activas consultando ai.embedding_progress_view. En esta vista, se proporcionan detalles sobre el progreso de la operación, incluido el porcentaje completado, el tiempo transcurrido y el tiempo restante estimado.

Para verificar el progreso, ejecuta la siguiente consulta:

SELECT
  table_name,
  content_column,
  embedding_column,
  model_id,
  percent_progress,
  status,
  elapsed_time,
  rows_processed,
  partition_root
FROM
  ai.embedding_progress_view;

En la vista, se proporciona la siguiente información:

Columna Descripción
table_name Es el nombre de la tabla o la partición que se procesa.
content_column Columna que contiene el contenido fuente de la incorporación.
embedding_column Columna en la que se almacenan los embeddings.
model_id Es el modelo que se usa para la generación.
percent_progress Es el porcentaje de la operación que se completó.
status Es el estado actual de la operación (p.ej., en ejecución, correcta).
elapsed_time Es el tiempo transcurrido desde que comenzó la operación.
rows_processed Es la cantidad de filas procesadas hasta el momento.
partition_root Nombre de la tabla particionada raíz.

Ejemplos para generar embeddings en automóviles

En esta sección, se proporcionan ejemplos para generar embeddings automáticamente con extremos de modelos registrados.

Modelo de embedding de OpenAI

Para generar embeddings con el extremo del modelo text-embedding-3-small registrado que proporciona OpenAI, ejecuta la siguiente instrucción:

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-3-small',
    table_name => 'user_reviews',
    content_column => 'content',
    embedding_column => 'content_embeddings'
);

Modelos de incorporación personalizados

En el caso de los modelos propios o compatibles de forma externa, debes definir funciones de transformación de entrada y salida, y registrarlas con ai.create_model. Si planeas usar la función de incorporación automática, debes especificar tanto las funciones de transformación escalar (por ejemplo, acme_text_input_transform, acme_text_output_transform) como las funciones de transformación por lotes (por ejemplo, acme_text_batch_input_transform, acme_text_batch_output_transform).

¿Qué sigue?