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

Android端使用NNAPI运行ONNX模型无法调用GPU的问题求助

如何让ONNX Runtime通过NNAPI调用Android GPU运行模型

问题描述

我在Android环境下尝试通过NNAPI调用GPU运行ONNX模型,设备是搭载Android 12的Galaxy S10 5G,且所有模型层均支持GPU。但当前代码完全未调用GPU,即使在addNnapi()方法中添加CPU_DISABLES选项也无效。

现有代码实现

MainActivity.kt 部分代码

val modelID = R.raw.mobilenetv2_int8
val mobelbyteArray = resources.openRawResource(modelID).readBytes()

val ortEnv = OrtEnvironment.getEnvironment()

val ortoption = SessionOptions()

ortoption.addNnapi()

var orisession = ortEnv?.createSession(mobelbyteArray,ortoption);

val height:Long = 224
val width:Long = 224
val batch_size = 1

val shape = longArrayOf(1, 3, height, width)
val env = OrtEnvironment.getEnvironment()

val imgData = FloatBuffer.allocate(height.toInt() * width.toInt() * batch_size * 3)

val inputName = orisession?.inputNames?.iterator()?.next()

env.use {
    val tensor = OnnxTensor.createTensor(env, imgData, shape)
    val startTime = SystemClock.uptimeMillis()
    tensor.use {
        val output = orisession?.run(Collections.singletonMap(inputName, tensor))

    }
}

build.gradle 配置

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.onnxrunkt'
    compileSdk 33

    defaultConfig {
        applicationId "com.example.onnxrunkt"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    /*
    aaptOptions{
        noCompress 'onnx'
    }

     */
}

dependencies {
    implementation 'com.microsoft.onnxruntime:onnxruntime-android:1.14.0'
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

解决方案

  • 配置NNAPI强制优先使用GPU
    默认addNnapi()不会强制指定设备,需要通过NnapiOptions明确配置执行优先级并禁用CPU,让NNAPI只能选择GPU:

    val ortoption = SessionOptions()
    val nnapiOptions = SessionOptions.NnapiOptions()
    // 优先选择最快的单推理设备(通常为GPU)
    nnapiOptions.setExecutionPreference(SessionOptions.NnapiOptions.ExecutionPreference.PREFER_FAST_SINGLE_ANSWER)
    // 禁用CPU,排除CPU执行路径
    nnapiOptions.setFlags(SessionOptions.NnapiOptions.Flag.DISABLE_CPU)
    ortoption.addNnapi(nnapiOptions)
    
  • 修复冗余的OrtEnvironment实例
    代码中创建了两个OrtEnvironment实例,可能导致资源冲突,统一使用单个实例:

    val ortEnv = OrtEnvironment.getEnvironment(OrtLoggingLevel.VERBOSE)
    // 后续创建Tensor时使用同一个ortEnv
    val tensor = OnnxTensor.createTensor(ortEnv, imgData, shape)
    
  • 开启ONNX模型的不压缩配置
    取消aaptOptions的注释,避免模型文件被压缩导致加载异常:

    aaptOptions {
        noCompress 'onnx'
    }
    
  • 添加日志与设备验证
    开启VERBOSE日志查看NNAPI设备选择情况,同时打印可用NNAPI设备:

    // 初始化环境时开启详细日志
    val ortEnv = OrtEnvironment.getEnvironment(OrtLoggingLevel.VERBOSE)
    
    // 打印所有可用的NNAPI设备
    val nnapiDevices = OrtEnvironment.getAvailableNnapiDevices()
    nnapiDevices.forEach { device ->
        Log.d("NNAPI_DEVICE", "设备名称: ${device.name}, 设备类型: ${device.type}")
    }
    

    通过日志可以确认NNAPI是否成功识别GPU,以及是否有层回退到CPU执行。

  • 验证GPU调用状态
    使用Android Studio的Profiler工具,查看GPU实时负载;或者运行推理时观察设备发热情况,GPU运行时通常会有明显的负载提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:23:14