尝试将自定义模型部署到 OpenSearch 中会引发运行时错误:KeyError:token_type_ids

问题描述 投票:0回答:1

对于特定用例,我必须将自定义模型部署到 OpenSearch 中,首先,我将 HuggingFace 模型导出到 TorchScript 中并已成功注册,然后我尝试部署它,但不幸的是部署操作失败并返回以下错误:

    {
  "model_id": "Guem7I4BM4PGcXAkFYKV",
  "task_type": "DEPLOY_MODEL",
  "function_name": "TEXT_EMBEDDING",
  "state": "FAILED",
  "worker_node": [
    "d7zdcxaASDyFKGX7AhlG0g",
    "5fc7S9yJQQCWarLbAnVESg",
    "TPu-1KznRzCwj8tQAgHOMQ"
  ],
  "create_time": 1713367889874,
  "last_update_time": 1713368035088,
  "error": """
                          {"d7zdcxaASDyFKGX7AhlG0g":"The following operation failed in the TorchScript interpreter.
                          \nTraceback of TorchScript, serialized code (most recent call last):
                          \n  File \"code/__torch__.py\", line 12, in forward
                          \n    input_ids = inputs[\"input_ids\"]
                          \n    attention_mask = inputs[\"attention_mask\"]
                          \n    input = inputs[\"token_type_ids\"]
                          \n            ~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
                          \n    _0 = (model).forward(input_ids, attention_mask, input, )
                          \n    return {\"sentence_embedding\": _0}
                          \n
                          \nTraceback of TorchScript, original code (most recent call last):
                          \n/Users/Library/Python/3.9/lib/python/site-packages/torch/jit/_trace.py(1074): trace_module
                          \n/Users/Library/Python/3.9/lib/python/site-packages/torch/jit/_trace.py(806): trace
                          \n/Users/opensearch/CustomModel/TEST/import_torch.py(43): export_to_torchscript
                          \n/Users/opensearch/CustomModel/TEST/import_torch.py(52): <module>
                          \nRuntimeError: KeyError: token_type_ids
                          \n","5fc7S9yJQQCWarLbAnVESg":"The following operation failed in the TorchScript interpreter.
                          \nTraceback of TorchScript, serialized code (most recent call last):
                          \n  File \"code/__torch__.py\", line 12, in forward
                          \n    input_ids = inputs[\"input_ids\"]
                          \n    attention_mask = inputs[\"attention_mask\"]
                          \n    input = inputs[\"token_type_ids\"]
                          \n            ~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
                          \n    _0 = (model).forward(input_ids, attention_mask, input, )
                          \n    return {\"sentence_embedding\": _0}
                          \n
                          \nTraceback of TorchScript, original code (most recent call last):
                          \n/Users/Library/Python/3.9/lib/python/site-packages/torch/jit/_trace.py(1074): trace_module
                          \n/Users/Library/Python/3.9/lib/python/site-packages/torch/jit/_trace.py(806): trace
                          \n/Users/opensearch/CustomModel/TEST/import_torch.py(43): export_to_torchscript
                          \n/Users/opensearch/CustomModel/TEST/import_torch.py(52): <module>
                          \nRuntimeError: KeyError: token_type_ids
                          \n","TPu-1KznRzCwj8tQAgHOMQ":"The following operation failed in the TorchScript interpreter.
                          \nTraceback of TorchScript, serialized code (most recent call last):
                          \n  File \"code/__torch__.py\", line 12, in forward
                          \n    input_ids = inputs[\"input_ids\"]
                          \n    attention_mask = inputs[\"attention_mask\"]
                          \n    input = inputs[\"token_type_ids\"]
                          \n            ~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
                          \n    _0 = (model).forward(input_ids, attention_mask, input, )
                          \n    return {\"sentence_embedding\": _0}
                          \n
                          \nTraceback of TorchScript, original code (most recent call last):
                          \n/Users/Library/Python/3.9/lib/python/site-packages/torch/jit/_trace.py(1074): trace_module
                          \n/Users/Library/Python/3.9/lib/python/site-packages/torch/jit/_trace.py(806): trace
                          \n/Users/opensearch/CustomModel/TEST/import_torch.py(43): export_to_torchscript
                          \n/Users/opensearch/CustomModel/TEST/import_torch.py(52): <module>
                          \nRuntimeError: KeyError: token_type_ids\n"}
    """,
  "is_async": true
}

这是我用来将模型导出到 TorchScript 的 python 脚本

import torch
from transformers import AutoModel, AutoTokenizer, PreTrainedTokenizer
from transformers.utils import PaddingStrategy
from sentence_transformers import SentenceTransformer


class TorchScriptWrapper(torch.nn.Module):
    def __init__(self, model):
        super(TorchScriptWrapper, self).__init__()
        self.model = model

    def forward(self, inputs: dict):
        with torch.no_grad():
            outputs = self.model(inputs)
        return {"sentence_embedding": outputs['sentence_embedding']}


def export_to_torchscript(model_name: str, is_sentence_transformer: bool, output_path: str, max_seq_length: int = 128):
    tokenizer: PreTrainedTokenizer = AutoTokenizer.from_pretrained(model_name)
    if is_sentence_transformer:
        model = SentenceTransformer(model_name, device="cpu")
    else:
        model = AutoModel.from_pretrained(model_name)
    model.eval()

    # Define example text
    text = "This is a test string"

    # Create inputs
    inputs = tokenizer(text, padding=PaddingStrategy.MAX_LENGTH, return_tensors="pt", max_length=max_seq_length)

    # Instantiate the wrapper class
    model_wrapper = TorchScriptWrapper(model)

    # Unpack HF batch encoding into a regular dict
    new_inputs = {}
    new_inputs["input_ids"] = inputs["input_ids"]
    new_inputs["attention_mask"] = inputs["attention_mask"]
    if inputs.get("token_type_ids", None) is not None:
        new_inputs["token_type_ids"] = inputs["token_type_ids"]

    # Trace the wrapper class
    traced_model = torch.jit.trace(model_wrapper, new_inputs, strict=False)

    # Save traced model to file
    traced_model.save(output_path)


if __name__ == "__main__":
    # Load pre-trained model and tokenizer
    model_name = "sentence-transformers/LaBSE"
    export_to_torchscript(model_name, True, output_path="torchscript_labse.pt")

PS:即使 token_type_ids 键是输入字典的一部分,也会发生错误

machine-learning artificial-intelligence large-language-model opensearch huggingface
1个回答
0
投票

问题已解决!

这是解决问题的更新脚本

from transformers import AutoModel, AutoTokenizer, PreTrainedTokenizer
from transformers.utils import PaddingStrategy
from sentence_transformers import SentenceTransformer


class TorchScriptWrapper(torch.nn.Module):
    def __init__(self, model):
        super(TorchScriptWrapper, self).__init__()
        self.model = model

    def forward(self, inputs: dict):
        inputs['token_type_ids'] = torch.zeros_like(inputs['attention_mask'], dtype=torch.int)
        with torch.no_grad():
            outputs = self.model(inputs)
        return {"sentence_embedding": outputs['sentence_embedding']}


def export_to_torchscript(model_name: str, is_sentence_transformer: bool, output_path: str, max_seq_length: int = 128):
    tokenizer: PreTrainedTokenizer = AutoTokenizer.from_pretrained(model_name)
    if is_sentence_transformer:
        model = SentenceTransformer(model_name, device="cpu")
    else:
        model = AutoModel.from_pretrained(model_name)
    model.eval()

    # Define example text
    text = "This is a test string"

    # Create inputs
    inputs = tokenizer(text, padding=PaddingStrategy.MAX_LENGTH, return_tensors="pt", max_length=max_seq_length)

    # Instantiate the wrapper class
    model_wrapper = TorchScriptWrapper(model)

    # Unpack HF batch encoding into a regular dict
    new_inputs = {}
    new_inputs["input_ids"] = inputs["input_ids"]
    new_inputs["attention_mask"] = inputs["attention_mask"]
    #if inputs.get("token_type_ids", None) is not None:
    #    new_inputs["token_type_ids"] = inputs["token_type_ids"]

    # Trace the wrapper class
    traced_model = torch.jit.trace(model_wrapper, new_inputs, strict=False)

    # Save traced model to file
    traced_model.save(output_path)


if __name__ == "__main__":
    # Load pre-trained model and tokenizer
    model_name = "sentence-transformers/LaBSE"
    export_to_torchscript(model_name, True, output_path="torchscript_labse.pt")
© www.soinside.com 2019 - 2024. All rights reserved.