
Clip como servicio es un servicio de alta escalabilidad de baja latencia para incrustar imágenes y texto. Se puede integrar fácilmente como un microservicio en soluciones de búsqueda neuronal.
⚡ Rápido : Servir los modelos de clip con Tensorrt, ONNX Runtime y Pytorch sin JIT con 800QP [*] . La transmisión dúplex que no es de bloqueo en las solicitudes y respuestas, diseñada para grandes datos y tareas de larga duración.
? Elástico : escalar horizontalmente hacia arriba y hacia abajo múltiples modelos de clip en una sola GPU, con equilibrio automático de carga.
? Fácil de usar : sin curva de aprendizaje, diseño minimalista en el cliente y el servidor. API intuitiva y consistente para la imagen y la incrustación de oraciones.
? Moderno : Soporte del cliente Async. Cambie fácilmente entre los protocolos GRPC, HTTP, WebSocket con TLS y compresión.
? Integración : integración suave con el ecosistema de búsqueda neuronal, incluidos Jina y Dargarray. Construya soluciones intermodales y multimodales en poco tiempo.
[*] con configuración predeterminada (réplica única, pytorch no jit) en GeForce RTX 3090.
| a través de https? | a través de GRPC? ⚡⚡ |
curl
-X POST https:// < your-inference-address > -http.wolf.jina.ai/post
-H ' Content-Type: application/json '
-H ' Authorization: <your access token> '
-d ' {"data":[{"text": "First do it"},
{"text": "then do it right"},
{"text": "then do it better"},
{"uri": "https://picsum.photos/200"}],
"execEndpoint":"/"} ' | # pip install clip-client
from clip_client import Client
c = Client (
'grpcs://<your-inference-address>-grpc.wolf.jina.ai' ,
credential = { 'Authorization' : '<your access token>' },
)
r = c . encode (
[
'First do it' ,
'then do it right' ,
'then do it better' ,
'https://picsum.photos/200' ,
]
)
print ( r ) |
Hay cuatro habilidades básicas de razonamiento visual: reconocimiento de objetos, conteo de objetos, reconocimiento de color y comprensión de la relación espacial. Probemos algunos:
Debe instalar
jq(un procesador JSON) para fastidiar los resultados.
| Imagen | a través de https? |
curl
-X POST https:// < your-inference-address > -http.wolf.jina.ai/post
-H ' Content-Type: application/json '
-H ' Authorization: <your access token> '
-d ' {"data":[{"uri": "https://picsum.photos/id/1/300/300",
"matches": [{"text": "there is a woman in the photo"},
{"text": "there is a man in the photo"}]}],
"execEndpoint":"/rank"} '
| jq " .data[].matches[] | (.text, .scores.clip_score.value) "da: | |
curl
-X POST https:// < your-inference-address > -http.wolf.jina.ai/post
-H ' Content-Type: application/json '
-H ' Authorization: <your access token> '
-d ' {"data":[{"uri": "https://picsum.photos/id/133/300/300",
"matches": [
{"text": "the blue car is on the left, the red car is on the right"},
{"text": "the blue car is on the right, the red car is on the left"},
{"text": "the blue car is on top of the red car"},
{"text": "the blue car is below the red car"}]}],
"execEndpoint":"/rank"} '
| jq " .data[].matches[] | (.text, .scores.clip_score.value) "da: | |
curl
-X POST https:// < your-inference-address > -http.wolf.jina.ai/post
-H ' Content-Type: application/json '
-H ' Authorization: <your access token> '
-d ' {"data":[{"uri": "https://picsum.photos/id/102/300/300",
"matches": [{"text": "this is a photo of one berry"},
{"text": "this is a photo of two berries"},
{"text": "this is a photo of three berries"},
{"text": "this is a photo of four berries"},
{"text": "this is a photo of five berries"},
{"text": "this is a photo of six berries"}]}],
"execEndpoint":"/rank"} '
| jq " .data[].matches[] | (.text, .scores.clip_score.value) "da: |
Clip-as-Service consta de dos paquetes de Python clip-server y clip-client que se pueden instalar de forma independiente . Ambos requieren Python 3.7+.
| Tiempo de ejecución de Pytorch ⚡ | Tiempo de ejecución de onnx ⚡⚡ | Tiempo de ejecución tensorrt ⚡⚡⚡ |
pip install clip-server | pip install " clip-server[onnx] " | pip install nvidia-pyindex
pip install " clip-server[tensorrt] " |
También puede alojar el servidor en Google Colab, aprovechando su GPU/TPU gratuita.
pip install clip-clientPuede ejecutar una verificación de conectividad simple después de la instalación.
| C/S | Dominio | Esperar salida |
|---|---|---|
| Servidor | python -m clip_server | ![]() |
| Cliente | from clip_client import Client
c = Client ( 'grpc://0.0.0.0:23456' )
c . profile () | ![]() |
Puede cambiar 0.0.0.0 a la dirección IP de Intranet o Pública para probar la conectividad a través de la red privada y pública.
python -m clip_server . Recuerde su dirección y puerto. from clip_client import Client
c = Client ( 'grpc://0.0.0.0:51000' ) r = c . encode ([ 'First do it' , 'then do it right' , 'then do it better' ])
print ( r . shape ) # [3, 512] r = c . encode ([ 'apple.png' , # local image
'https://clip-as-service.jina.ai/_static/favicon.png' , # remote image
'data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7' ]) # in image URI
print ( r . shape ) # [3, 512]Se pueden encontrar más guías completas de los usuarios de servidor y cliente en los documentos.
Construyamos una búsqueda de texto a imagen usando clip como servicio. A saber, un usuario puede ingresar una oración y el programa devuelve imágenes coincidentes. Usaremos el paquete de conjunto de datos y Darterray totalmente parecido. Tenga en cuenta que Darterray se incluye dentro de clip-client como una dependencia aguas arriba, por lo que no necesita instalarlo por separado.
Primero cargamos imágenes. Simplemente puede sacarlos de Jina Cloud:
from docarray import DocumentArray
da = DocumentArray . pull ( 'ttl-original' , show_progress = True , local_cache = True )Alternativamente, puede ir a un sitio web oficial, descomponer y cargar imágenes:
from docarray import DocumentArray
da = DocumentArray . from_files ([ 'left/*.jpg' , 'right/*.jpg' ])El conjunto de datos contiene 12,032 imágenes, por lo que puede llevar un tiempo extraer. Una vez hecho esto, puede visualizarlo y obtener el primer sabor de esas imágenes:
da . plot_image_sprites ()
Inicie el servidor con python -m clip_server . Digamos que está en 0.0.0.0:51000 con el protocolo GRPC (obtendrá esta información después de ejecutar el servidor).
Crea un script de cliente de Python:
from clip_client import Client
c = Client ( server = 'grpc://0.0.0.0:51000' )
da = c . encode ( da , show_progress = True )Dependiendo de su GPU y su red de cliente cliente, puede llevar un tiempo incrustar 12k imágenes. En mi caso, tardó unos dos minutos.
Si eres impaciente o no tienes una GPU, esperar puede ser un infierno. En este caso, simplemente puede extraer nuestro conjunto de datos de imagen pre-codificado:
from docarray import DocumentArray
da = DocumentArray . pull ( 'ttl-embedding' , show_progress = True , local_cache = True )Construyamos un indicador simple para permitir que un usuario escriba la oración:
while True :
vec = c . encode ([ input ( 'sentence> ' )])
r = da . find ( query = vec , limit = 9 )
r [ 0 ]. plot_image_sprites ()Ahora puede ingresar oraciones en inglés arbitrarias y ver las imágenes coincidentes principales. La búsqueda es rápida e instintiva. Vamos a divertirnos:
| "Una papa feliz" | "Una ai super malvada" | "Un chico disfrutando de su hamburguesa" |
|---|---|---|
|
|
|
| "El profesor Cat es muy serio" | "Un ingeniero de ego vive con los padres" | "No habrá mañana, así que vamos a comer poco saludables" |
|---|---|---|
|
|
|
Guardemos el resultado de incrustación para nuestro próximo ejemplo:
da . save_binary ( 'ttl-image' )También podemos cambiar la entrada y la salida del último programa para lograr la búsqueda de imagen a texto. Precisamente, dada una imagen de consulta, encuentre la oración que mejor describe la imagen.
Usemos todas las oraciones del libro "Orgullo y prejuicio".
from docarray import Document , DocumentArray
d = Document ( uri = 'https://www.gutenberg.org/files/1342/1342-0.txt' ). load_uri_to_text ()
da = DocumentArray (
Document ( text = s . strip ()) for s in d . text . replace ( ' r n ' , '' ). split ( '.' ) if s . strip ()
)Veamos lo que tenemos:
da . summary () Documents Summary
Length 6403
Homogenous Documents True
Common Attributes ('id', 'text')
Attributes Summary
Attribute Data type #Unique values Has empty value
──────────────────────────────────────────────────────────
id ('str',) 6403 False
text ('str',) 6030 False
Ahora codifique estas 6.403 oraciones, puede tomar 10 segundos o menos dependiendo de su GPU y red:
from clip_client import Client
c = Client ( 'grpc://0.0.0.0:51000' )
r = c . encode ( da , show_progress = True )Nuevamente, para las personas impacientes o que no tienen una GPU, hemos preparado un conjunto de datos de texto pre-codificado:
from docarray import DocumentArray
da = DocumentArray . pull ( 'ttl-textual' , show_progress = True , local_cache = True )Cargamos nuestra incrustación de imagen previamente almacenada, muestreamos aleatoriamente 10 documentos de imagen, luego encontremos el vecino más cercano de cada uno.
from docarray import DocumentArray
img_da = DocumentArray . load_binary ( 'ttl-image' )
for d in img_da . sample ( 10 ):
print ( da . find ( d . embedding , limit = 1 )[ 0 ]. text )¡Tiempo divertido! Nota, a diferencia del ejemplo anterior, aquí la entrada es una imagen y la oración es la salida. Todas las oraciones provienen del libro "Orgullo y prejuicio".
|
|
|
|
|
| Además, había verdad en su aspecto | Gardiner sonrió | Cómo se llama | Por tiempo del té, sin embargo, la dosis había sido suficiente y Sr. | No te ves bien |
|
|
|
|
|
| "¡Un jugador!" Ella lloró | Si mencionas mi nombre en The Bell, serás atendido a | No importa el cabello de la señorita Lizzy | Elizabeth pronto será la esposa del señor | Los vi la noche anterior al último |
Desde 0.3.0 Clip como servicio agrega un punto final nuevo /rank que vuelve a clasificar las coincidencias intermodales de acuerdo con su probabilidad conjunta en el modelo de clip. Por ejemplo, dado un documento de imagen con algunas coincidencias de oración predefinidas como a continuación:
from clip_client import Client
from docarray import Document
c = Client ( server = 'grpc://0.0.0.0:51000' )
r = c . rank (
[
Document (
uri = '.github/README-img/rerank.png' ,
matches = [
Document ( text = f'a photo of a { p } ' )
for p in (
'control room' ,
'lecture room' ,
'conference room' ,
'podium indoor' ,
'television studio' ,
)
],
)
]
)
print ( r [ '@m' , [ 'text' , 'scores__clip_score__value' ]]) [['a photo of a television studio', 'a photo of a conference room', 'a photo of a lecture room', 'a photo of a control room', 'a photo of a podium indoor'],
[0.9920725226402283, 0.006038925610482693, 0.0009973491542041302, 0.00078492151806131, 0.00010626466246321797]]
Uno puede ver ahora a photo of a television studio se clasifica en la parte superior con la puntuación clip_score a 0.992 . En la práctica, uno puede usar este punto final para volver a clasificar el resultado coincidente de otro sistema de búsqueda, para mejorar la calidad de búsqueda intermodal.
![]() | ![]() |
En el proyecto Dall · E Flow, se requiere que el clip clasifique los resultados generados de Dall · E. Tiene un albacea envuelto en la parte superior clip-client , que llama .arank() - la versión async de .rank() ::
from clip_client import Client
from jina import Executor , requests , DocumentArray
class ReRank ( Executor ):
def __init__ ( self , clip_server : str , ** kwargs ):
super (). __init__ ( ** kwargs )
self . _client = Client ( server = clip_server )
@ requests ( on = '/' )
async def rerank ( self , docs : DocumentArray , ** kwargs ):
return await self . _client . arank ( docs )
Intrigado? Eso es solo rascar la superficie de lo que es capaz de clip como servicio. Lea nuestros documentos para aprender más.
Clip como servicio está respaldado por Jina Ai y con licencia bajo Apache-2.0. Estamos contratando activamente ingenieros de IA, ingenieros de soluciones para construir el próximo ecosistema de búsqueda neural en código abierto.