Pytorch 模型转换为 Onnx Inference 问题

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

我已使用提供的工具将模型从 Huggingface 转换为 Onnx:

optimum-cli export onnx --model deepset/roberta-base-squad2 "roberta-base-squad2" --framework pt

转换完成,没有错误。

我用下面的代码来进行推断:

        // QnA Service Configuration:
        // Site: https://huggingface.co/deepset/roberta-base-squad2
        Configuration QnAConfig = new Configuration(@"C:\Bert\dslimL\model.onnx")
        {

            ConfigurationFileName = "config.json",
            HasTokenTypeIds = false,
            IsCasedModel = false,
            MaximumNumberOfTokens = 1,
            MergesFileName = "merges.txt",
            NumberOfTokens = 5,
            Repository = "deepset/roberta-large-squad2",
            TokenizerName = TokenizerName.Tokenizer,
            VocabularyFileName = "vocab.json"
        };

        Configuration = QnAConfig;
        labelsCount = Configuration.ModelConfiguration.IdTolabel.Count;

        var sessionOptions = new SessionOptions()
        {
            ExecutionMode = ExecutionMode.ORT_PARALLEL,
            EnableCpuMemArena = true,
            EnableMemoryPattern = true,
            EnableProfiling = true,
            GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL,
            InterOpNumThreads = 10
        };
        sessionOptions.AppendExecutionProvider_CPU(0);

        Session = new InferenceSession(Configuration.ModelPath, sessionOptions);

        // Set Question and Context:
        Schema.Question = sentence;
        Schema.Context = Context;

        // Process SubContext:
        Schema.Sentence = $"'question': '{sentence}',"
                        + $"   'context': '{Context}'";

        // 
        var Start = Configuration.Tokenizer.Model.TokenToId("<s>");
        var End = Configuration.Tokenizer.Model.TokenToId("</s>");
        var Pad = Configuration.Tokenizer.Model.TokenToId("<pad>");

        // 
        var result = Configuration.Tokenizer.Encode(Schema.Sentence);
        var decode = Configuration.Tokenizer.Decode(result.Ids);

        // 
        var inputArray = result.Ids.ToLongArray((long)Start, (long)End);
        var MyAttentionMask = AttentionMaskHelpers.BuildMask(20, 20, -0);

        // 
        long[] attMask = new long[inputArray.Length];
        for (int i = 0; i < inputArray.Length; i++)
            if (i < inputArray.Length * 0.5)
                attMask[i] = 1;
            else
                attMask[i] = 0;

        // 
        var tensorInputIds = TensorExtensions.ConvertToTensor(inputArray, inputArray.Length);
        var attention_Mask = TensorExtensions.ConvertToTensor(attMask, inputArray.Length);

        var inputs = new List<NamedOnnxValue>
        {

            NamedOnnxValue.CreateFromTensor("input_ids", tensorInputIds),
            NamedOnnxValue.CreateFromTensor("attention_mask", attention_Mask),
            //NamedOnnxValue.CreateFromTensor("token_type_ids", attention_Mask)
        };


        ////////////////////////////////////////////////////////////////////////////////////////
        /// # Convert the answer (tokens) back to the original text
        /// # Score: score from the model
        /// # Start: Index of the first character of the answer in the context string
        /// # End: Index of the character following the last character of the answer in the context string
        /// # Answer: Plain text of the answer
        /// See: https://github.com/huggingface/transformers/blob/main/src/transformers/pipelines/question_answering.py
        /// Run the Session, infering an Output:
        var inputMeta = Session.InputMetadata;
        var output = Session.Run(inputs);

        // Init a new Answer Id List:
        List<int> AnswerIds = new List<int>();

        // The Output Logits: new List<float>(); // 
        List<float> startLogits = output[0].AsEnumerable<float>().ToList();
        List<float> endLogits = output[1].AsEnumerable<float>().ToList();

        // Get Indexes of the Context:
        float start = startLogits.Max();
        float end = endLogits.Max();
        Schema.Score = ((start + end) / 10.0f);

        // Get Indexes of the top scores:
        Schema.StartIndex = startLogits.IndexOf(start);
        Schema.EndIndex = endLogits.IndexOf(end);

        // Tokenise the Sentence:
        TokenizerResult Tokens = Configuration.Tokenizer.Encode(Schema.Sentence);

        // Get the List of Ids:
        for (int i = Schema.StartIndex; i <= Schema.EndIndex; i++)
            AnswerIds.Add(Convert.ToInt32(inputArray[i]));

        // Get the Answer:
        Schema.Answer = Configuration.Tokenizer.Decode(AnswerIds).Trim();

我正在使用:

 using Microsoft.ML.Tokenizers;

分词器的工作原理:

Tokenizer = new Tokenizer(new EnglishRoberta(vocabFilePath, mergeFilePath, dictPath), RobertaPreTokenizer.Instance);

我已经检查了令牌和 ID,它们是匹配的,因此令牌化过程很好。

问题:所有预测都会导致开始索引和结束索引为零索引,这给了我一个开始标记结果,因此如果开始标记是“”,那么即使分数是好还是坏,结果也是“”。

模型使用 PY 脚本在 Python 中运行良好,没有错误!

from transformers import AutoModelForQuestionAnswering, AutoTokenizer, pipeline

model_name = "deepset/roberta-base-squad2"

model = AutoModelForQuestionAnswering.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

nlp = pipeline('question-answering', model=model_name, tokenizer=model_name)
QA_input = {
'question': 'Why is model conversion important?',
'context': 'The option to convert models between FARM and transformers gives freedom to the user and let people easily switch between frameworks.'
}
res = nlp(QA_input)

print(res)

我相信这个问题与 Onnx 和 Onnxruntime 环境直接相关,除非我做错了什么。但是,我还有其他模型使用类似的代码。

我尝试过其他型号:

  • deepset/罗伯塔基地-squad2
  • 深/罗伯塔-大-小队2

所有型号都有同样的问题。

我相信 onnxruntime 的 bug 比大多数人愿意承认的还要多,真是耻辱!

c# pytorch artificial-intelligence onnx onnxruntime
1个回答
0
投票

您似乎在使用从 Hugging Face 模型转换而来的 ONNX 模型进行推理时遇到了问题。以下一些建议可能可以帮助您排除故障并可能解决问题: 输入格式:确保提供给 ONNX 模型的输入格式与模型期望的输入格式匹配。检查输入 ID 和注意掩码的格式是否正确并符合模型的输入要求。输出解析:验证您是否正确解析 ONNX 模型的输出。检查输出张量是否包含答案范围的开始和结束位置的预期 logits 或分数。会话初始化:仔细检查 ONNX 推理会话的初始化。确保针对您的环境正确配置所有会话选项和执行提供程序。模型兼容性:确认 ONNX 转换过程成功,并且生成的 ONNX 模型与您正在使用的 ONNX 运行时版本兼容。某些模型或操作可能不完全支持,或者可能需要额外的配置。调试:添加打印语句或日志记录以在推理过程中检查中间变量和输出。这可以帮助识别输入或输出数据中的任何意外行为或不一致。 ONNX 运行时版本:确保您使用的 ONNX 运行时版本与转换后的 ONNX 模型兼容。更新或降级 ONNX 运行时版本可能会解决兼容性问题。模型评估:考虑使用其他推理框架或工具评估 ONNX 模型,以在当前环境之外验证其性能和正确性。这可以帮助确定问题是特定于 ONNX 运行时还是与模型本身相关。社区支持:从 ONNX 或 Hugging Face 社区论坛或 GitHub 存储库寻求帮助。其他用户可能也遇到过类似的问题,可以根据他们的经验提供指导或解决方案。 🤔

© www.soinside.com 2019 - 2024. All rights reserved.