Modelo de aprendizado de máquina tradicional (experimental)#

Saiba como usar o Xinference para inferir modelos tradicionais de aprendizado de máquina. No Xinference, esses modelos flexíveis e escaláveis são chamados de modelos flexíveis.

Adicionado na versão v1.7.1: Esta funcionalidade está disponível desde a versão v1.7.1. Atualmente, a API ainda não é estável e pode sofrer alterações em iterações futuras.

Introdução#

Modelos de aprendizado de máquina tradicionais ainda podem desempenhar um papel importante em um ecossistema centrado em grandes modelos.

O Xinference oferece capacidades flexíveis de extensão para inferência de modelos tradicionais de machine learning. Ele possui suporte nativo para carregar e executar os seguintes tipos de modelo:

  • O HuggingFace Pipeline, que utiliza modelos hospedados pela HuggingFace, pode ser usado para tarefas como classificação.

  • Use a ModelScope Pipeline do ModelScope para modelos, que pode ser usado para tarefas como classificação.

  • YOLO é utilizado para detecção de imagens e tarefas relacionadas à visão computacional.

O Xinference suporta vários modelos tradicionais de aprendizado de máquina. Para cada uma das categorias mencionadas acima, demonstraremos passo a passo, por meio de um exemplo representativo, como realizar inferência na plataforma Xinference.

Casos de suporte a modelos integrados#

Modelo de Pipeline HuggingFace#

Primeiro, tomamos como exemplo o FacebookAI/roberta-large-mnli. Este modelo é um modelo de classificação zero-shot. Para outros tipos de modelos, ao registrar, basta especificar a tarefa correspondente (que também é um parâmetro do Pipeline).

Faça o download do modelo para o seguinte caminho:

/path/to/roberta-large-mnli

Em seguida, demonstramos como registrar o modelo flexível na Xinference Web UI. Nos próximos exemplos, a menos que necessário, pularemos as operações de interface e focaremos na lógica central.

actor

O arquivo JSON do modelo personalizado correspondente é o seguinte:

{
    "model_name": "roberta-large-mnli",
    "model_id": null,
    "model_revision": null,
    "model_hub": "huggingface",
    "model_description": "roberta-large-mnli is the RoBERTa large model fine-tuned on the Multi-Genre Natural Language Inference (MNLI) corpus. The model is a pretrained model on English language text using a masked language modeling (MLM) objective.",
    "model_uri": "/path/to/roberta-large-mnli",
    "launcher": "xinference.model.flexible.launchers.transformers",
    "launcher_args": "{\"task\": \"zero-shot-classification\"}",
    "virtualenv": {
        "packages": [],
        "inherit_pip_config": true,
        "index_url": null,
        "extra_index_url": null,
        "find_links": null,
        "trusted_host": null,
        "no_build_isolation": null
    },
    "is_builtin": false
}

Consulte a seção register_custom_model para saber como registrar um modelo por código ou linha de comando.

Em seguida, na interface web, selecione Modelo de inicialização /Modelo personalizado /Modelo flexível para carregar o modelo. O processo de carregamento é o mesmo que para outros tipos de modelo.

Ao usar a linha de comando, lembre-se de especificar o parâmetro --model-type flexible.

Após o modelo ser carregado com sucesso, podemos realizar a inferência da seguinte maneira.

curl -X 'POST' \
  'http://<XINFERENCE_HOST>:<XINFERENCE_PORT>/v1/flexible/infers' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "roberta-large-mnli",
    "args": [
      "one day I will see the world",
      ["travel", "cooking", "dancing"]
    ]
  }'

ModelScope Pipeline Model#

ModelScope Pipeline models são muito semelhantes aos modelos Huggingface, a única diferença está no launcher utilizado.

Tomamos como exemplo um modelo de classificação zero-shot no ModelScope. O modelo é iic/nlp_structbert_zero-shot-classification_chinese-base.

Aqui utilizamos o recurso de ambiente virtual de modelo do Xinference. Como o modelo usado neste exemplo requer transformers==4.50.3 para funcionar corretamente, para isolar o ambiente de execução, utilizamos ambiente virtual ao registrar o modelo.

A sintaxe para especificar pacotes personalizados ao registrar um modelo é a mesma que para pacotes comuns, mas existem alguns casos especiais. Como o ambiente virtual ainda se baseia nos site-packages do interpretador Python em que o Xinference está sendo executado, precisamos incluir explicitamente #system_numpy#. O nome do pacote deve ser envolvido por #system_xx# para garantir que o ambiente virtual criado seja consistente com o ambiente base; caso contrário, isso pode facilmente causar erros em tempo de execução.

Forma de registro (Web UI):

actor

Arquivo JSON correspondente:

{
    "model_name": "nlp_structbert_zero-shot-classification_chinese-base",
    "model_id": null,
    "model_revision": null,
    "model_hub": "huggingface",
    "model_description": "This is a model description.",
    "model_uri": "/Users/xuyeqin/Downloads/models/nlp_structbert_zero-shot-classification_chinese-base",
    "launcher": "xinference.model.flexible.launchers.modelscope",
    "launcher_args": "{\"task\": \"zero-shot-classification\"}",
    "virtualenv": {
        "packages": [
            "transformers==4.50.3",
            "#system_numpy#"
        ],
        "inherit_pip_config": true,
        "index_url": "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple",
        "extra_index_url": null,
        "find_links": null,
        "trusted_host": null,
        "no_build_isolation": null
    },
    "is_builtin": false
}

model inference

curl -X 'POST' \
  'http://<XINFERENCE_HOST>:<XINFERENCE_PORT>/v1/flexible/infers' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "nlp_structbert_zero-shot-classification_chinese-base",
    "args": [
      "世界那么大,我想去看看"
    ],
    "candidate_labels": ["家居", "旅游", "科技", "军事", "游戏", "故事"]
  }'

YOLO#

YOLO é um modelo popular de detecção de objetos em tempo real, amplamente utilizado em cenários de detecção de imagens e análise de vídeo.

Primeiro, baixe os pesos do YOLO. Aqui, usaremos o arquivo yolov11s.pt como exemplo.

Arquivo JSON de definição do modelo:

{
    "model_name": "yolo11s",
    "model_id": null,
    "model_revision": null,
    "model_hub": "huggingface",
    "model_description": "YOLO is a popular real-time object detection model, widely used in image detection and video analysis scenarios.",
    "model_uri": "/Users/xuyeqin/Downloads/models/yolo11s.pt",
    "launcher": "xinference.model.flexible.launchers.yolo",
    "launcher_args": "{}",
    "virtualenv": {
        "packages": [
            "ultralytics",
            "#system_numpy#"
        ],
        "inherit_pip_config": true,
        "index_url": "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple",
        "extra_index_url": null,
        "find_links": null,
        "trusted_host": null,
        "no_build_isolation": null
    },
    "is_builtin": false
}

model inference

import requests
from PIL import Image
import io
import base64
from xinference.client import Client

client = Client("http://<XINFERENCE_HOST>:<XINFERENCE_PORT>")
model = client.get_model("yolo11s")

url = "https://ultralytics.com/images/bus.jpg"

response = requests.get(url)
response.raise_for_status()

img = Image.open(io.BytesIO(response.content))

buffered = io.BytesIO()
img.save(buffered, format="JPEG")
img_bytes = buffered.getvalue()
img_base64 = base64.b64encode(img_bytes).decode('utf-8')

model.infer(source=img_base64)

Escreva um modelo flexível personalizado#

Primeiro, implementamos um launcher personalizado simples para classificação de sentimentos. Neste exemplo, não utilizamos nenhum peso de modelo real, portanto a função load não executa nenhuma operação de carregamento de modelo.

# my_flexible_model.py

from xinference.model.flexible import FlexibleModel


class RuleBasedSentimentModel(FlexibleModel):
    def load(self):
        self.pos_words = self.config.get("pos", ["good", "happy", "great"])
        self.neg_words = self.config.get("neg", ["bad", "sad", "terrible"])

    def infer(self, text: str):
        score = 0
        words = text.lower().split()
        for w in words:
            if w in self.pos_words:
                score += 1
            elif w in self.neg_words:
                score -= 1
        return {"score": score}


def launcher(model_uid: str, model_spec: FlexibleModel, **kwargs) -> FlexibleModel:
    # get model path,
    # in this example, we do not use it, so it's empty
    model_path = model_spec.model_uri
    return RuleBasedSentimentModel(model_uid=model_uid, model_path=model_path, config=kwargs)

A definição JSON do modelo é a seguinte:

{
    "model_name": "my-flexible-model",
    "model_id": null,
    "model_revision": null,
    "model_hub": "huggingface",
    "model_description": "This is a model description.",
    "model_uri": "/path/to/model",
    "launcher": "my_flexible_model.launcher",
    "launcher_args": "{\"pos\": [\"good\", \"happy\", \"great\", \"nice\"]}",
    "virtualenv": {
        "packages": [],
        "inherit_pip_config": true,
        "index_url": null,
        "extra_index_url": null,
        "find_links": null,
        "trusted_host": null,
        "no_build_isolation": null
    },
    "is_builtin": false
}

Aqui estendemos o modelo passando um valor personalizado de pos.

Por fim, vamos verificar o resultado:

from xinference.client import Client

client = Client("http://127.0.0.1:9997")

model = client.get_model("my-flexible-model")

model.infer("I feel nice and am happy today")

conclusão#

O launcher flexível de modelos integrado do Xinference pode ser encontrado no Github, e contribuições para adicionar suporte a mais modelos de aprendizado de máquina tradicionais são bem-vindas!