ML.NET中T5文本摘要模型数组越界问题求助
ML.NET T5文本摘要索引越界问题排查与解决
问题核心原因
- 输出张量维度不匹配:模型输出是三维float32张量[1,128,512],但你的
CombinedOutput类中Output属性仅初始化为长度128的VBuffer<float>,ML.NET在尝试将三维张量数据填充到一维VBuffer时,会因索引超出范围抛出异常。 - 输入张量形状未正确映射:模型期望输入是二维张量[1,128],但你传入的是一维数组
long[]和float[],ML.NET未自动扩展维度,导致模型内部处理时维度不匹配。
具体解决方向
1. 修正输出类的张量类型
将CombinedOutput中的Output属性改为兼容三维张量的类型,ML.NET支持用float[,,]或Tensor<float>接收三维输出:
internal class CombinedOutput { [ColumnName("input.103")] public float[,,] Output { get; set; } // 也可以用更贴合ML.NET张量处理的类型 // public Tensor<float> Output { get; set; } }
无需在构造函数中初始化,ML.NET会根据模型输出维度自动分配内存
2. 确保输入张量维度匹配模型要求
模型期望输入是[1,128]的二维张量,需在模型构建阶段添加Reshape操作,将一维数组转换为二维张量:
在GetCombinedModel()方法中加载ONNX模型前,添加维度调整步骤:
var pipeline = mlContext.Transforms.Reshape("input_ids", shape: new[] { 1, 128 }) .Append(mlContext.Transforms.Reshape("attention_mask", shape: new[] { 1, 128 })) .Append(mlContext.Model.LoadOnnxModel("path/to/your/t5/model.onnx")); // 预训练模型用EmptyDataView初始化模型 var model = pipeline.Fit(mlContext.Data.LoadFromEnumerable(new CombinedInput[] { }));
3. 验证Tokenizer的截断逻辑
强制校验inputIds和attention_mask的长度,确保两者都严格截断到128:
// 截断后校验并修正长度 if(inputData.InputIds.Length != 128) inputData.InputIds = inputData.InputIds.Take(128).ToArray(); if(inputData.AttentionMask.Length != 128) inputData.AttentionMask = inputData.AttentionMask.Take(128).ToArray();
4. 检查ONNX模型加载时的输入输出映射
确保加载ONNX模型时,输入输出列名完全匹配Netron检测到的名称(input_ids、attention_mask、input.103),避免因列名不匹配导致内部数据错乱。
额外调试建议
将输入数据转换为IDataView后打印列信息,确认输入维度是否正确:
var dataView = mlContext.Data.LoadFromEnumerable(new[] { inputData }); var schema = dataView.Schema; foreach (var column in schema) { Console.WriteLine($"Column: {column.Name}, Type: {column.Type}, Shape: {column.Type.GetTensorShape()}"); }
内容的提问来源于stack exchange,提问作者Bob Logan
相关产品推荐
相关产品推荐

