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

寻求在Fortran代码中调用已训练TensorFlow/Flux模型的高效优雅方案

针对Fortran集成已训练ML模型的高效方案

一、TensorFlow模型部署优化方案

1. 转ONNX格式后用Fortran ONNX运行时加载

这是最通用的跨语言部署方式,避开直接调用TensorFlow复杂C API的繁琐:

  • 第一步:Python中用tf2onnx将TensorFlow模型转成ONNX格式:
    import tensorflow as tf
    import tf2onnx
    
    # 加载训练好的模型
    model = tf.keras.models.load_model("your_tf_model.h5")
    # 导出为ONNX文件
    tf2onnx.convert.from_keras(model, output_path="model.onnx")
    
  • 第二步:使用Fortran的ONNX Runtime绑定库加载模型并推理,核心示例:
    use onnxruntime
    implicit none
    
    type(ORTEnv) :: env
    type(ORTSession) :: session
    real, allocatable :: input(:,:), output(:,:)
    
    ! 初始化环境与会话
    call env%init()
    call session%init(env, "model.onnx")
    
    ! 准备输入数据(按模型维度调整)
    allocate(input(1, 784))
    input = ... ! 填充你的输入数据
    
    ! 执行推理
    call session%run(["input"], [input], ["output"], [output])
    
    ! 清理资源
    call session%destroy()
    call env%destroy()
    

该方案无需依赖TensorFlow完整库,ONNX Runtime轻量且接口简洁,比fortran_calls_tensorflow更易维护。

2. 使用TensorFlow Lite部署

若模型无需TensorFlow高级特性,TFLite是更轻量的选择:

  • 导出TFLite模型:
    converter = tf.lite.TFLiteConverter.from_keras_model(model)
    tflite_model = converter.convert()
    with open("model.tflite", "wb") as f:
        f.write(tflite_model)
    
  • Fortran通过iso_c_binding调用TFLite的C API,核心逻辑为初始化解释器、分配张量、运行推理,接口比原生TensorFlow C API简洁得多,适合轻量部署场景。

二、Julia Flux模型部署优化方案

1. 转ONNX格式复用Fortran ONNX运行时

和TensorFlow思路一致,用ONNX.jl将Flux模型导出为ONNX:

using Flux, ONNX

# 加载Flux模型
model = Chain(Dense(784, 256, relu), Dense(256, 10))
# 导出为ONNX(需传入示例输入确定维度)
ONNX.save(model, "flux_model.onnx", (rand(784),))

之后直接用Fortran的ONNX Runtime加载推理,完全无需Julia与Fortran的嵌入集成,是最优雅的跨语言方案。

2. 生成Julia动态链接库供Fortran调用

若必须保留Julia运行环境(如依赖Flux特定算子),可将Julia模型编译为C兼容动态库:

  • Julia端代码(生成动态库):
    using Flux, Libdl, BSON
    
    # 定义推理函数
    function predict(input::Vector{Float64})::Vector{Float64}
        model = Chain(Dense(784, 256, relu), Dense(256, 10))
        # 加载已训练权重
        weights = BSON.load("flux_weights.bson")[:weights]
        Flux.loadparams!(model, weights)
        return model(input)
    end
    
    # 导出为C兼容函数
    ccall(:jl_export_symbol, Cvoid, (Cstring,), "predict")
    # 用PackageCompiler生成独立动态库(示例简化)
    using PackageCompiler
    create_library(".", "libfluxmodel", precompile_execution_file="precompile.jl")
    
  • Fortran端调用:
    use iso_c_binding
    implicit none
    
    interface
        function predict(input, input_len) bind(C, name="predict")
            import :: c_double, c_int
            real(c_double), intent(in) :: input(*)
            integer(c_int), intent(in) :: input_len
            real(c_double) :: predict(*)
        end function
    end interface
    
    real(c_double), allocatable :: input(:), output(:)
    allocate(input(784))
    input = ... ! 填充输入数据
    allocate(output(10))
    output = predict(input, int(size(input), c_int))
    

该方式比借鉴Python集成思路更直接,Julia原生支持生成C兼容接口,无需额外中间层。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:02:49