introdutório
O DashInfer-VLM é uma arquitetura de inferência para grandes modelos VLMs multimodais visuais, especialmente otimizada para a aceleração da inferência dos modelos VL da Qwen. A maior diferença entre o DashInfer-VLM e outras estruturas de aceleração de inferência para VLMs é que ele separa a parte VIT da parte LLM, e a VIT e a LLM são executadas em paralelo sem interferir uma na outra. sem interferir um no outro.
Isso é caracterizado pelo fato de que o pré-processamento de imagem e vídeo no VLM, bem como a parte de extração de recursos do VIT, não interromperá a geração do LLM, e também pode ser uma arquitetura separada de VIT/LLM, que é a primeira estrutura de serviço VLM na comunidade de código aberto a usar essa arquitetura.
Em uma implementação com várias placas, ele tem uma unidade de processamento ViT em cada placa, o que proporciona uma vantagem de desempenho muito significativa em cenários de vídeo e de várias imagens.
Além disso, para a parte ViT, ele oferece suporte ao armazenamento em cache na memória para que não haja necessidade de recalcular o ViT repetidamente em várias rodadas de diálogo.
Abaixo está um diagrama de sua arquitetura e sua configuração de acordo com a parte de 4 cartões 72B.
O diagrama de arquitetura descreve o processo e a arquitetura:
- Na parte ViT, muitas elicitações de inferência podem ser usadas para inferência, como TensorRT ou onnxruntime (a exportação do modelo onnx será realizada na parte ViT do modelo dentro da estrutura).
- Na seção LLM, o DashInfer é usado para inferência.
- Parte do cache, suporte ao resultado do ViT Cache de memória, parte do LLM Cache de prefixo, parte do LLM Cache de prefixo multimodal (não ativado por padrão)
Endereço do código:
https://github.com/modelscope/dash-infer
Endereço do documento:
https://dashinfer.readthedocs.io/en/latest/vlm/vlm_offline_inference_en.html
melhores práticas
Experimente o DashInfer na aritmética de GPU gratuita da comunidade Magic Hitch:
O primeiro passo é a instalação do dashinfer-vlm e do TensorRT. # Primeiro, instale os pacotes necessários importar os # Baixe e instale o dashinfer versão 2.0.0rc2 # Faça o download e extraia os pacotes do TensorRT usando o wget, se necessário. # pip install dashinfer 2.0.0rc2 #!pip install https://github.com/modelscope/dash-infer/releases/download/v2.0.0-rc2/dashinfer-2.0.0rc2-cp310-cp310-manylinux_2_ 17_x86_64.manylinux2014_x86_64.whl #!wget https://modelscope.oss-cn-beijing.aliyuncs.com/releases/TensorRT-10.6.0.26.Linux.x86_64-gnu.cuda-12.6.tar.gz #!tar -xvzf TensorRT-10.6.0.26.Linux.x86_64-gnu.cuda-12.6.tar.gz # Faça o download localmente e substitua pela URL correspondente ao modelscope # Instale o dashinfer; recomendamos instalá-lo localmente, pois o pacote é grande. #!wget https://modelscope.oss-cn-beijing.aliyuncs.com/releases/dashinfer-2.0.0rc3-cp310-cp310-manylinux_2_17_x86_64. manylinux2014_x86_64.whl #!pip install . /dashinfer-2.0.0rc3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl # instalar o dashinfer vlm #!pip install dashinfer-vlm #! pip install cliente OpenAI #!pip install openai==1.56.2 # Instale o pacote Python para o TensorRT, abra-o a partir do download e instale-o. #!pip install TensorRT-10.6.0.26/python/tensorrt-10.6.0-cp310-none-linux_x86_64.whl
O TensorRT requer a configuração de variáveis de ambiente:
importar os # Obtenha o caminho para a biblioteca de tempo de execução do TensorRT trt_runtime_path = os.getcwd() + "/TensorRT-10.6.0.26/lib/" # Obtenha o valor atual da variável de ambiente LD_LIBRARY_PATH current_ld_library_path = os.environ.get('LD_LIBRARY_PATH', '') # Adicione o novo caminho ao valor existente if current_ld_library_path. # if LD
Depois que o ambiente estiver instalado, inicie o dashinfer vlm para raciocinar sobre os modelos e formar um servidor compatível com openai, onde os modelos podem ser alterados para 7B, 72B, etc.
Toda a memória da GPU no ambiente é usada por padrão.
!dashinfer_vlm_serve --model qwen/Qwen2-VL-2B-Instruct --port 8000 --host 127.0.0.1
Esse processo inicializa o DashInfer, bem como o mecanismo externo usado pelo ViT (nesse caso, o TensorRT), e inicia um serviço openai.
A visualização desses registros indica que o TRT foi inicializado com êxito:
A visualização desses registros indica que o DashInfer foi inicializado com êxito:
A visualização desses registros indica que o serviço openai foi inicializado com êxito:
Quando toda a inicialização for bem-sucedida, você poderá abrir outro notebook para o cliente e o benchmarking.
Endereço do notebook:https://modelscope.cn/notebook/share/ipynb/6ea987c5/vl-start-server.ipynb
Demonstração de compreensão de imagens
Demonstrar uma demonstração para compreensão de imagens com várias imagens:
# Instale a versão necessária do cliente OpenAI !pip install openai==1.56.2 # O suporte a VL requer um cliente OpenAI recente. from openai import OpenAI # Inicialize o cliente OpenAI cliente = OpenAI( base_url="http://localhost:8000/v1", api_key="EMPTY", api_key="EMPTY api_key="EMPTY" ) # Preparar a chamada de API para uma conclusão de bate-papo response = client.chat.completions.create( model="model", messages=[ { "role": "user", "content": [ "content": [ { "type": "text", "text": "Essas imagens são diferentes?"}, { "role": "user", "content": [ { "type": "image_url", "image_url": {"type": "content", "text": "Are these images different?"}, {"type": "image_url", "text": "Are these images different? "image_url": { "url": "https://farm4.staticflickr.com/3075/3168662394_7d7103de7d_z_d.jpg", { "type": "image_url", "image_url": { } }, { "type": "image_url", { "image_url": { "url": "https://farm2.staticflickr.com/1533/26541536141_41abe98db3_z_d.jpg", } } ] } ], stream=True, max_completion_tokens=1024, } max_completion_tokens=1024, }, ], stream=True, max_completion_tokens=1024, } temperature=0.1, ) ) # Processar a resposta transmitida full_response = "" for chunk in response. # Acrescente o conteúdo delta à resposta completa full_response += chunk.choices[0].delta.content print("." , end="") # Imprima um ponto para cada bloco recebido # Imprimir a resposta completa print(f"\nImagem: Resposta completa:\n{full_response}")
Demonstração de compreensão de vídeo
Como o openai não define uma interface de vídeo padrão, este documento fornece um tipo video_url, que faz o download automático, extrai quadros e analisa o vídeo.
Exemplo de vídeo # !pip install openai==1.56.2 # Certifique-se de que o cliente OpenAI seja compatível com os recursos de link de vídeo. from openai import OpenAI # Inicialize o cliente OpenAI cliente = OpenAI( base_url="http://localhost:8000/v1", api_key="EMPTY", api_key="EMPTY api_key="EMPTY" ) # Criar uma solicitação de conclusão de bate-papo com um URL de vídeo response = client.chat.completions.create( model="model", messages=[ { "role": "user", "content": [ "content": [ { "type": "text", "text": "Gere uma descrição atraente que eu possa carregar junto com o vídeo. "text": "Gere uma descrição atraente que eu possa carregar junto com o vídeo." }, " }, { "type": "video_url", "text": "Gere uma descrição atraente que eu possa carregar junto com o vídeo. "video_url": { "url": "https://cloud.video.taobao.com/vod/JCM2awgFE2C2vsACpDESXZ3h5_iQ5yCZCypmjtEs2Ck.mp4", "fps": 2 } } ] } ], max_completion_tokens=1024, max_completion_tokens=1024, top_p=0.5, top_p=0,5, temperature=0,1, frequency_penalty=1,05, stream=True, ) ) # Processar a resposta de streaming full_response = "" for chunk in response. # Acrescente o conteúdo delta do trecho à resposta completa full_response += chunk.choices[0].delta.content print("." , end="") # Indicar o progresso com pontos # Imprimir a resposta completa print(f"\nResposta completa: \n{full_response}")
referência
Use a imagem acima para entender o EXEMPLO e simplesmente faça um teste multicorrente para testar a taxa de transferência.
# benchmark!pip install openai==1.56.2 importar time import concurrent.futures from openai import OpenAI O # inicializa o cliente OpenAI. cliente = OpenAI( base_url="http://localhost:8000/v1", api_key="EMPTY", api_key="EMPTY api_key="EMPTY" ) Parâmetros da solicitação # model = "model" (modelo) messages = [ { "role": "user", "content": [ "content": [ { "type": "text", "text": "Are these images different?"}, { "role": "user", "content": [ "type": "text", "text": "Are these images different? { "type": "image_url", "image_url": {"type": "content", "text": "Are these images different?"}, {"type": "image_url", "text": "Are these images different? "image_url": { "url": "https://farm4.staticflickr.com/3075/3168662394_7d7103de7d_z_d.jpg", { "type": "image_url", "image_url": { } }, { "type": "image_url", { "image_url": { "url": "https://farm2.staticflickr.com/1533/26541536141_41abe98db3_z_d.jpg", } } ] } ] Função de solicitação simultânea # def send_request(): start_time = time.time() response = client.chat.completions.create( model=model, messages=messages, stream=False, max_completion_tokens max_completion_tokens=1024, temperature=0.1, ) ) end_time = time.time() latência = end_time - start_time retornar latência Função de benchmark # def benchmark(num_requests, num_workers): latencies = [] start_time = time.time() with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor: futures = [executor.submit(send_request) for _ in range(num_requests)] for future in concurrent.futures.as_completed(futures): [executor.submit(send_request) for _ in range(num_requests)] latencies.append(future.result()) end_time = time.time() total_time = end_time - start_time qps = num_requests / total_time average_latency = sum(latencies) / len(latencies) throughput = num_requests * 1024 / total_time # Supondo um tamanho de resposta de 1024 bytes por solicitação print(f "Total Time: {total_time:.2f} seconds") print(f "QPS: {qps:.2f}") print(f "Average Latency: {average_latency:.2f} seconds") Entrada do programa principal do # if __name__ == "__main__": num_requests = 100 num_requests = 100 # Número total de solicitações. num_workers = 10 # threads de trabalho simultâneos benchmark(num_requests, num_workers)
Resultados do teste:
Endereço do notebook:https://modelscope.cn/notebook/share/ipynb/5560603a/vl-test-and-benchmark.ipynb
Comparação de desempenho abrangente e vLLM:
Para comparar e contrastar o desempenho do vLLM de forma mais abrangente e precisa, usamos o OpenGVLab/InternVL-Chat-V1-2-SFT-Data para comparar conversas simultâneas simples, múltiplas e de várias rodadas em diferentes tamanhos de modelos, e os scripts de reprodução detalhados são mostrados no link, e os resultados são os seguintes:
É possível observar que o DashInfer tem algumas vantagens de desempenho em todos os casos, especialmente no diálogo de várias rodadas.