Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9a505d9
[layer] add cast layer
sachin-nntrainer Oct 14, 2025
1b0b0f4
[layer] update weight layer
sachin-nntrainer Oct 14, 2025
e1652b4
[docs] add onnx document
sachin-nntrainer Oct 14, 2025
5e94952
[onnx] add simple attention block example
sachin-nntrainer Oct 14, 2025
59212d8
[layers] add some layers for onnx converting
sachin-nntrainer Oct 14, 2025
d296ce8
[draft][onnx] onnx interpreter for llama
sachin-nntrainer Oct 14, 2025
cb9da0e
[onnx] fix compilation issue related to the weight layer
sachin-nntrainer Oct 14, 2025
892069a
[ONNX][draft] Weight loading from bin files for onnx models
sachin-nntrainer Oct 14, 2025
7d15c88
[ONNX] Solved Slice layer setTensorDim erroe
sachin-nntrainer Oct 14, 2025
3380f13
matmul error unfinished
sachin-nntrainer Oct 14, 2025
29eb120
Python modelling and utility scripts
sachin-nntrainer Oct 14, 2025
f874fd8
ONNX Interpreter changes: Added support for parsing pow op
sachin-nntrainer Oct 14, 2025
532870b
layer to supports Qwen3B
sachin-nntrainer Oct 14, 2025
67617e8
Added weight loading support via layer name
sachin-nntrainer Oct 14, 2025
f4cfa5c
Debug ops for accuracy:No changes
sachin-nntrainer Oct 14, 2025
9bd39a3
Adding save2raw in main.cpp and changing example value
sachin-nntrainer Oct 14, 2025
ca210db
remove unwanted files
sachin-nntrainer Oct 14, 2025
85d866a
unwanted cout statement
sachin-nntrainer Oct 14, 2025
ed7081e
Added python env reqs
sachin-nntrainer Oct 27, 2025
be73c12
- Enabled Android build support for ONNX models by integrating protob…
niket-agarwal Oct 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
# ignore build directory
/build
/builddir
/third_party
/protobuf-25.2
/subprojects
.cache/
.idea/

Expand Down Expand Up @@ -71,3 +74,8 @@ test/jni/googletest/
ctre-unicode.hpp
encoder.hpp
json.hpp

*.bin
onnx__*
*.onnx
*.weight
4 changes: 2 additions & 2 deletions Applications/ONNX/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ LOCAL_ARM_NEON := true
LOCAL_CFLAGS += -std=c++17 -Ofast -mcpu=cortex-a53 -Ilz4-nougat/lib
LOCAL_LDFLAGS += -Llz4-nougat/lib/obj/local/$(TARGET_ARCH_ABI)/
LOCAL_CXXFLAGS += -std=c++17 -frtti
LOCAL_CFLAGS += -pthread -fexceptions -fopenmp
LOCAL_CFLAGS += -pthread -fexceptions -fopenmp -static-openmp
LOCAL_LDFLAGS += -fexceptions
LOCAL_MODULE_TAGS := optional
LOCAL_ARM_MODE := arm
LOCAL_MODULE := nntrainer_onnx_example
LOCAL_LDLIBS := -llog -landroid -fopenmp
LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp

LOCAL_SRC_FILES := main.cpp

Expand Down
14 changes: 0 additions & 14 deletions Applications/ONNX/jni/add_example.onnx

This file was deleted.

Binary file added Applications/ONNX/jni/llama_example.onnx
Binary file not shown.
89 changes: 83 additions & 6 deletions Applications/ONNX/jni/main.cpp
Original file line number Diff line number Diff line change
@@ -1,48 +1,125 @@
// SPDX-License-Identifier: Apache-2.0
/**
* Copyright (C) 2025 Seungbaek Hong <[email protected]>
*
* Copyright (C) 2025 Sachin Singh <[email protected]>
* @file main.cpp
* @date 26 Feb 2025
* @date 14 October 2025
* @brief onnx example using nntrainer-onnx-api
* @see https://github.com/nnstreamer/nntrainer
* @author Seungbaek Hong <sb92.honge@samsung.com>
* @author Sachin Singh <sachin.3@samsung.com>
* @bug No known bugs except for NYI items
*
* Updated on 16 Oct 2025 to add debug output for Android execution
*/

#include <fstream>
#include <iostream>
#include <layer.h>
#include <model.h>
#include <nntrainer-api-common.h>
#include <optimizer.h>
#include <util_func.h>

void saveToRaw(const float *data, size_t size, const std::string &filename) {
std::ofstream out(filename, std::ios::binary);
if (!out) {
std::cerr << "Error: Cannot open file " << filename << " for writing.\n";
return;
}

out.write(reinterpret_cast<const char *>(data), size * sizeof(float));
out.close();

std::cout << std::endl << ".bin generated successfully !";
}

int main() {
auto model = ml::train::createModel();

std::cout << "--------------------------------------Create Model "
"Done--------------------------------------"
<< std::endl;
try {
std::string path = "../../../../Applications/ONNX/jni/add_example.onnx";
// std::string path = "/storage_data/snap/sumon/sumon-98/nntrainer/Applications/ONNX/jni/qwen3_model_one_layer_no_cast.onnx";
std::string path = "./qwen3_model_one_layer_no_cast.onnx";
model->load(path, ml::train::ModelFormat::MODEL_FORMAT_ONNX);
} catch (const std::exception &e) {
std::cerr << "Error during load: " << e.what() << "\n";
return 1;
}

std::cout << "--------------------------------------Load Model "
"Done--------------------------------------"
<< std::endl;
try {
model->compile();
model->compile(ml::train::ExecutionMode::INFERENCE);
} catch (const std::exception &e) {
std::cerr << "Error during compile: " << e.what() << "\n";
return 1;
}

std::cout << "--------------------------------------Compile Model "
"Done--------------------------------------"
<< std::endl;
try {
model->initialize();
} catch (const std::exception &e) {
std::cerr << "Error during initialize: " << e.what() << "\n";
return 1;
}

std::cout << "--------------------------------------Initialize Model Done--------------------------------------" << std::endl;
std::cout << "Skipping model summary..." << std::endl;

std::cout << "Starting model summary..." << std::endl;
model->summarize(std::cout, ML_TRAIN_SUMMARY_MODEL);
std::cout << "Finished model summary." << std::endl;

std::cout << "--------------------------------------Summarize Model "
"Done--------------------------------------"
<< std::endl;

std::cout << "Loading weights..." << std::endl;
std::string weight_path = "./qwen_weights_one_layer_no_cast/";
std::cout << "Loading weights from: " << weight_path << std::endl;
std::cout << "Loading weights from: " << weight_path << std::endl;
try {
model->load(weight_path, ml::train::ModelFormat::MODEL_FORMAT_BIN);
std::cout << "Weights loaded successfully" << std::endl;
} catch (std::exception &e) {
std::cerr << "Error during loading weights: " << e.what() << "\n";
return 1;
}
std::cout<<"starting inferencing!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
float *input = new float[1];
float *sin = new float[128];
float *cos = new float[128];
float *epsilon = new float[1];

input[0] = 52;

for (int i = 0; i < 128; i++) {
sin[i] = 0;
cos[i] = 1;
}
epsilon[0] = 1e-6;

std::vector<float *> in;

in.push_back(epsilon);
in.push_back(sin);
in.push_back(cos);
in.push_back(input);

auto ans = model->inference(1, in);

std::cout << "-------------------------------------------Inference "
"Done--------------------------------------------"
<< std::endl;

for (auto it : ans) {
saveToRaw(it, 151936,
"../../../../Applications/ONNX/jni/nntrainer_logits.bin");
}

return 0;
}
9 changes: 9 additions & 0 deletions Applications/ONNX/python/qwen3/compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import numpy as np

arr1 = np.fromfile("./modelling_logits.bin",dtype="float32").reshape(1,151936)
arr2 = np.fromfile("../../jni/nntrainer_logits.bin",dtype="float32").reshape(1,151936)

if(np.allclose(arr1,arr2,atol=1e-4,rtol=1e-4)):
print("equal")
else:
print("not equal")
47 changes: 47 additions & 0 deletions Applications/ONNX/python/qwen3/create_bin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import onnx
import numpy as np
import json
import os
import shutil
from onnx import numpy_helper, TensorProto

def cleanName(name):
if name.startswith('/'):
name = name[1:]

name = name.replace('/', '_')
name = name.replace('.', '_')
name = name.replace(':', '_')
name = name.lower()

return name


model = onnx.load("./qwen3_model.onnx", load_external_data=True)

metadata = {}

script_dir = os.path.dirname(os.path.abspath(__file__))
folder = os.path.join(script_dir, "bins")
if os.path.exists(folder):
shutil.rmtree(folder)
os.makedirs(folder)

for tensor in model.graph.initializer:
arr = numpy_helper.to_array(tensor).astype(np.float32)

filename = f"./bins/{cleanName(tensor.name)}.bin"
arr.tofile(filename)

# Save metadata (name, dtype, shape, file)
metadata[tensor.name] = {
"file": filename,
"tensor name": tensor.name,
"dtype": TensorProto.DataType.Name(tensor.data_type),
"shape": list(arr.shape)
}

print(f"Saved {tensor.name} -> {filename}, dtype={arr.dtype}, shape={arr.shape}")

with open("./weights_metadata.json", "w") as f:
json.dump(metadata, f, indent=4)
Loading