You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用tf.loadGraphModelSync([ModelJSON, ArrayBuffer])报错求助

问题描述

我想制作一个能运行TensorFlow.js模型的独立HTML文档,操作流程如下:

  1. 在Python中将模型保存为.h5文件
  2. 通过tensorflowjs_convert --input_format keras ...命令转换模型,得到包含model.json(确认可正常加载)和单权重文件group1-shard1of1.bin的目录
  3. 将两个文件内容做Base64编码后,以Data URI嵌入HTML,代码如下:
const modelURI = "data:application/json;base64,<Data Here>";
const weightsURI = "data:application/octet-stream;base64,<Data Here>";

Promise.all([fetch(modelURI), fetch(weightsURI)])
    .then(function(resp) {
        return Promise.all([resp[0].json(), resp[1].arrayBuffer()]);
    })
    .then(function(data) {
        tf.loadGraphModelSync([data[0], data[1]]);
    });

但loadGraphModelSync持续报错:

Uncaught (in promise) TypeError: n is null
    value graph_model.js:212
    value graph_model.js:180
    value graph_model.js:167
    loadGraphModelSync graph_model.js:699

我确定问题出在传入的ArrayBuffer,但对TensorFlow.js不熟悉无法定位原因。查阅相关PR得知ArrayBuffer是权重串联列表,但没有具体格式信息。求问权重格式或Base64数据加载的替代方法。

编辑1:使用未压缩TensorFlow.js包得到详细错误:

32091 |             if (metadata.structuredOutputKeys != null) {
32092 |                 this.structuredOutputKeys = metadata.structuredOutputKeys;
32093 |             }
32094 |         }
32095 |         this.signature = signature;
32096 |         this.version = "".concat(graph.versions.producer, ".").concat(graph.versions.minConsumer);
                                         ^
TypeError: null is not an object (evaluating 'graph.versions')
      at .../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32096:34
      at .../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32063:16
      at .../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32053:16
      at loadGraphModelSync (.../node_modules/@tensorflow/tfjs-converter/dist/tf-converter.node.js:32577:5)
      at .../src/index.ts:14:9

解决方法

核心问题解析

  1. 模型类型不匹配:用tensorflowjs_convert转换Keras .h5模型得到的是Layers模型,而非Graph模型。loadGraphModelSync是针对TensorFlow GraphDef格式模型的加载方法,强行调用会因为Layers模型结构中没有Graph模型的graph字段,导致graph.versions为空报错。
  2. 参数格式错误:loadGraphModelSync不支持直接传入[模型JSON, 权重Buffer]的数组组合,需要符合特定的参数结构。

正确实现代码

const modelBase64 = "<你的model.json的Base64字符串>";
const weightsBase64 = "<你的group1-shard1of1.bin的Base64字符串>";

// 直接解码Base64得到模型JSON
const modelJson = JSON.parse(atob(modelBase64));
// 解码Base64得到权重ArrayBuffer
const weightsBuffer = Uint8Array.from(atob(weightsBase64), c => c.charCodeAt(0)).buffer;

// 构造符合要求的模型工件对象
const artifacts = {
  modelTopology: modelJson.modelTopology,
  weightsManifest: modelJson.weightsManifest,
  weightData: weightsBuffer
};

// 用Layers模型的同步加载方法加载模型
const model = tf.loadLayersModelSync({
  load: () => Promise.resolve(artifacts)
});

// 验证模型加载成功
console.log("模型加载完成");
console.log(model.summary());

关键说明

  • 无需通过fetch处理Data URI,直接用atob解码Base64字符串更高效,避免异步请求的额外开销。
  • tensorflowjs_convert生成的权重文件是按照weightsManifest中的描述顺序拼接的,直接传入解码后的Buffer即可匹配加载要求。
  • 如果需要异步加载,可将loadLayersModelSync替换为loadLayersModel,并调整相关同步逻辑。

内容的提问来源于stack exchange,提问作者Generic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:22:35