es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo recuperar un vector por su ID desde Python

Tengo un índice de faiss y quiero usar algunos de los embeddings en mi script de Python. La selección de embeddings debe hacerse por ID. Como faiss está escrito en C++, se utiliza swig como una API.

Supongo que la función que necesito es “reconstruct” en el siguiente enlace:

/** Reconstruct a stored vector (or an approximation if lossy coding)
 *
 * this function may not be defined for some indexes
 * @param key         id of the vector to reconstruct
 * @param recons      reconstucted vector (size d)
 */
virtual void reconstruct(idx_t key, float* recons) const;

Por lo tanto, llamo a este método en Python, por ejemplo:

vector = index.reconstruct(0)

Pero esto resulta en el siguiente error:

> vector = index.reconstruct(0) 
> File "lib/python3.8/site-packages/faiss/__init__.py", line 406, in replacement_reconstruct
>     self.reconstruct_c(key, swig_ptr(x))
> File "lib/python3.8/site-packages/faiss/swigfaiss.py", line 1897, in reconstruct
>     return _swigfaiss.IndexFlat_reconstruct(self, key, recons)
> TypeError: in method 'IndexFlat_reconstruct', argument 2 of type 'faiss::Index::idx_t' python-BaseException

¿Alguien tiene alguna idea de qué está mal en mi enfoque?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el mensaje de error se debe a un problema de incompatibilidad de tipos entre el script de Python y el código de C++. El segundo argumento de reconstruct() debería ser un array de números de punto flotante, pero parece que no se está pasando correctamente desde el script de Python.

    Una posible solución podría ser especificar el tipo de datos del argumento explícitamente en el script de Python. Puedes intentar convertir el array de números de punto flotante a un array de ctypes del mismo tipo que se espera en C++:

    import ctypes
    import numpy as np
    
    # define los tipos de datos
    FloatArray = ctypes.POINTER(ctypes.c_float)
    Int64 = ctypes.c_int64
    
    # crea un array de numpy de números de punto flotante
    recons = np.zeros((d,), dtype=np.float32)
    
    # convierte el array de numpy a un array de ctypes
    recons_c = recons.ctypes.data_as(FloatArray)
    
    # llama a la función reconstruct con los argumentos de ctypes
    index.reconstruct(Int64(key), recons_c)
    

    Alternativamente, puedes utilizar el wrapper de Python generado por SWIG para la API de C++ directamente:

    import faiss.swigfaiss as swigfaiss
    
    # crea un array de numpy de números de punto flotante
    recons = np.zeros((d,), dtype=np.float32)
    
    # llama a la función generada por SWIG con los argumentos
    swigfaiss.IndexFlat_reconstruct(index.index_ptr, key, recons)
    

    Espero que una de estas soluciones funcione para ti.

Comments are closed.