当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > LiteRT SignatureDef 多输入模型怎么按签名准备推理张量

LiteRT SignatureDef 多输入模型怎么按签名准备推理张量

来源:17golang原创 2026-10-13 07:31:46 0浏览 收藏

LiteRT 多输入模型接入时,最稳妥的做法是先读取模型暴露的 SignatureDef,再用签名中的输入名称组织张量。不要根据内部 tensor index 猜测参数顺序:签名 key 决定调用哪个入口,输入名称决定每个张量绑定到哪里,输出名称决定从结果字典里取什么。

官方文档:https://developers.google.com/edge/litert/conversion/tensorflow/signatures

先记住这条排查线索
  • signature key 是入口名称,例如 serving_default。
  • 多输入调用的关键字必须使用签名定义的输入名称,例如 image 和 scale。
  • 返回值是按输出名称组织的字典,先读清单再写绑定代码,能避免顺序猜测。

问题现场:为什么输入数量对了,调用仍然报错

常见现象是模型明明有两个输入,代码也准备了两个 NumPy 数组,但调用时仍出现名称不存在、形状不匹配或结果取不到。初步看像是张量数据有问题,实际上更常见的原因是把“模型内部的张量编号”当成了“应用层的签名参数名”。

SignatureDef 把模型包装成一个有名字的入口:一个模型可以有多个 signature key;每个入口有自己的输入名称和输出名称。多输入模型因此不是“按数组顺序塞进去”,而是“按名称把每个数组交给对应输入”。

先确认 signature 的三层命名

排查时把名称拆成三层,思路会清楚很多:

层级示例作用
signature keyserving_default选择模型的一个入口
输入名称image、scale把应用张量绑定到入口参数
输出名称scores、label从推理结果字典取回对应结果
LiteRT SignatureDef 中 signature key、多输入名称和多输出名称的关系说明图
图1:LiteRT SignatureDef 的入口、输入和输出名称关系说明图,不是截图或运行证据。

这三层名称可能与内部 tensor 名称不同。应用代码应依赖签名契约;只有在做底层诊断时,才有必要继续查看 tensor 的内部信息。

动手查看:先把模型的签名清单打印出来

不要先写 runner 调用。先用解释器读取签名清单,确认到底有哪些入口、输入和输出。下面的示例只展示查看方式,model.tflite 需要替换为自己的模型文件。

import tensorflow as tf

# 加载模型并读取签名元数据;这里不执行推理。
interpreter = tf.lite.Interpreter(model_path="model.tflite")
signature_list = interpreter.get_signature_list()

# 逐个查看入口、输入名和输出名,避免凭经验猜参数。
for signature_key, spec in signature_list.items():
    print("signature:", signature_key)
    print("inputs:", spec["inputs"])
    print("outputs:", spec["outputs"])

如果清单返回类似 {"serving_default": {"inputs": ["image", "scale"], "outputs": ["scores", "label"]}},就说明这个入口需要两个命名输入,并会返回两个命名输出。这里的名称是文章示例,实际值以你的模型清单为准。

定位原因:多输入张量要同时满足名称、形状和类型

有了名称之后,再准备输入张量。名称解决“交给谁”,形状和数据类型解决“交什么”。例如图像输入常见为四维数组,缩放参数可能是单元素数组;这只是结构示意,不能代替模型自身的签名约束。

import numpy as np

# 按模型签名准备两个输入;形状和 dtype 必须换成你的实际定义。
image = np.zeros((1, 224, 224, 3), dtype=np.float32)
scale = np.array([0.5], dtype=np.float32)

# 用名称保存输入,后面交给 signature runner 做绑定。
inputs = {
    "image": image,
    "scale": scale,
}

# 这里打印的是准备结果,不代表已经得到真实推理输出。
for name, tensor in inputs.items():
    print(name, tensor.shape, tensor.dtype)

如果这里的形状与模型实际签名不同,后续调用会失败;如果模型要求整数类型,也不能只把 float32 强行传入。先根据签名和模型文档确定输入规格,再决定是否需要归一化、转型或增加 batch 维度。

修复调用:用 signature runner 按名称传入多个输入

确认入口名后,通过 get_signature_runner 取得该入口的调用对象。多输入时把每个签名输入写成一个关键字参数;这样即使内部 tensor index 变化,应用代码仍然围绕稳定的签名名称工作。

# 选择清单中已经确认的入口。
runner = interpreter.get_signature_runner("serving_default")

# 关键字名称必须与 signature 的 inputs 完全一致。
result = runner(
    image=image,
    scale=scale,
)

# 输出同样按签名名称读取,避免假设返回值的顺序。
scores = result["scores"]
label = result["label"]
print("scores shape:", scores.shape)
print("label:", label)

这里的 result 是按输出名称组织的映射。不要把它当成固定位置的列表,也不要把 image 与 scale 的变量顺序当成模型契约;真正的契约是签名中的名称与输入输出定义。

LiteRT SignatureDef 输入名称映射到内部 tensor index 并按名称执行推理的结构说明图
图2:签名输入名称映射到内部 tensor index 的静态说明图,不代表实际模型执行时序。

继续排查:三类错误应该看哪里

现象先检查修复方向
找不到 signature keyget_signature_list() 的顶层键使用实际入口名,不要默认写 serving_default
输入名称不存在当前入口的 inputs 列表把调用关键字改成签名名称,避免使用 tensor index
形状或类型错误对应输入的 shape、dtype 和 batch 约束调整数组形状、类型或预处理,不要只改参数顺序
输出取值失败当前入口的 outputs 列表按输出名称读取字典,不猜测返回位置

如果模型包含多个 signature,还要确认当前 runner 选的是正确入口。两个入口可能使用不同的输入输出集合;只看模型“总共有几个输入”并不能判断某一次调用需要哪些参数。

并发边界:同一个 interpreter 不要让 runner 同时执行

签名调用解决的是参数绑定,不等于自动获得线程安全。官方 LiteRT 签名文档明确提示,同一个 interpreter 的 signature runner 不保证可以并发执行。服务端或多线程场景应为并发请求设计清晰的 interpreter 生命周期,例如每个工作单元使用独立实例,或在共享实例外层建立可靠的串行保护。

import threading

interpreter_lock = threading.Lock()

def infer_one(runner, image, scale):
    # 共享 interpreter 时,把一次完整调用放在同一个临界区。
    with interpreter_lock:
        return runner(image=image, scale=scale)

# 若需要更高并发,应评估创建多个 interpreter,而不是移除这把锁。

这段代码表达的是并发边界,不是性能结论。是否使用锁、实例池还是请求串行化,取决于模型大小、设备资源和服务的延迟目标;本文不把某一种部署方式当成通用答案。

总结:把签名当成多输入模型的调用契约

遇到 LiteRT 多输入调用问题时,按“读取清单—确认入口—准备张量—按名调用—按名取结果—复查并发”的顺序处理。只要不把 tensor index、数组顺序和签名名称混为一谈,绝大多数名称绑定问题都能在调用前定位。

常见问题

必须先调用 allocate_tensors() 才能使用 signature runner 吗?

本文的重点是签名名称绑定;是否需要额外分配步骤要以你所用 LiteRT API 和运行时版本的官方接口为准。先完成签名清单读取,再按照对应 API 的生命周期要求初始化解释器。

输入名称可以直接写成 tensor index 吗?

不可以。签名 runner 接收的是签名定义的输入名称;内部 index 只是模型实现层信息,不能替代调用契约。

多输入的顺序需要和模型转换时一致吗?

应用调用应按名称绑定,而不是依赖参数出现顺序。真正需要一致的是每个名称对应的数据形状、类型和语义。

为什么输出字典里没有我预期的字段?

先打印当前 signature 的 outputs,再确认选中的入口是否正确。不同 signature 可能暴露不同输出名称,不要从另一个入口复制字段名。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
青漫漫画怎么找新作和追更?推荐、更新频道、榜单与收藏入口说明青漫漫画怎么找新作和追更?推荐、更新频道、榜单与收藏入口说明
上一篇
青漫漫画怎么找新作和追更?推荐、更新频道、榜单与收藏入口说明
LiteRT int8 量化结果异常时怎么检查代表性数据集的输入范围
下一篇
LiteRT int8 量化结果异常时怎么检查代表性数据集的输入范围
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    452次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    520次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    536次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    482次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    304次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码