Stack Overflow When Loading A Onnx Imported Model

by ADMIN 50 views

Introduction

In this article, we will discuss a stack overflow issue that occurs when loading a model imported from ONNX. The issue is caused by a recursive function call that leads to a stack overflow. We will go through the steps to reproduce the issue, the expected behavior, and the complete stacktrace.

Describe the Bug

The bug occurs when loading a model imported from ONNX using the burn-import generated code. The from_file function is called with a file path and a device, and it attempts to load the model from the file. However, the load function calls the load_record function, which in turn calls the from_embedded function, leading to a recursive function call that causes a stack overflow.

To Reproduce

To reproduce the issue, follow these steps:

  1. Download the ONNX model from the GitHub repository: https://github.com/Star-Clouds/CenterFace/raw/master/models/onnx/centerface.onnx
  2. Import the model using the following code:
ModelGen::new()
    .input("models/detection/centerface.onnx")
    .out_dir("models/detection")
    .record_type(RecordType::Bincode)
    .embed_states(false)
    .run_from_script();
  1. Load the model using the following code:
mod centerface {
    include!(concat!(env!("OUT_DIR"), "/models/detection/centerface.rs"));
}
let model: centerface::Model<Backend> = centerface::Model::default();

Expected Behavior

The expected behavior is that the model is loaded successfully without any errors.

Desktop (please complete the following information):

  • OS: Windows 10

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional Context

The issue is not specific to the ONNX model and can occur with any model imported from ONNX. The issue is caused by the recursive function call in the burn-import generated code.

Complete Stacktrace

The complete stacktrace is as follows:

__chkstk (@__chkstk:15)
<burn_core::record::recorder::_::<impl serde::de::Deserialize for burn_core::record::recorder::BurnRecord<I,B>>::deserialize::__Visitor<I,B> as serde::de::Visitor>::visit_seq (
<bincode::features::serde::de_borrowed::SerdeDecoder<DE> as serde::de::Deserializer>::deserialize_tuple 
<bincode::features::serde::de_borrowed::SerdeDecoder<DE> as serde::de::Deserializer>::deserialize_struct
union enum2{{content}}lt;core::result::Result<burn_core::record::recorder::BurnRecord<deepface_rs::detection::centerface::centerface::ModelRecordItem<burn_ndarray::backend::NdArray<f32,i64,i8>,burn_core::record::settings::FullPrecisionSettings>,burn_ndarray::backend::NdArray<f32,i64,i8> >,enum2{{content}}lt;bincode::error::DecodeError> > > burn_core::record::recorder::_::impl$0::deserialize<deepface_rs::detection::centerface::centerface::ModelRecordItem<burn_ndarray::backend::NdArray<f32,i64,i8>,burn_core::record::settings::FullPrecisionSettings>,burn_ndarray::backend::NdArray<f32,i64,i8>,bincode::features::serde::de_borrowed::SerdeDecoder<bincode::de::decoder::DecoderImpl<bincode::de::read::SliceReader,bincode::config::Configuration<bincode::config::LittleEndian,bincode::config::Varint,bincode::config::NoLimit>,tuple{{content}}lt;> > > >(struct bincode::features::serde::de_borrowed::SerdeDecoder<bincode::de::decoder::DecoderImpl<bincode::de::read::SliceReader,bincode::config::Configuration<bincode::config::LittleEndian,bincode::config::Varint,bincode::config::NoLimit>,tuple{{content}}lt;> > >)
union enum2{{content}}lt;core::result::Result<bincode::features::serde::BorrowCompat<burn_core::record::recorder::BurnRecord<deepface_rs::detection::centerface::centerface::ModelRecordItem<burn_ndarray::backend::NdArray<f32,i64,i8>,burn_core::record::settings::FullPrecisionSettings>,burn_ndarray::backend::NdArray<f32,i64,i8> > >,enum2{{content}}lt;bincode::error::DecodeError> > > bincode::features::serde::impl$9::borrow_decode<burn_core::record::recorder::BurnRecord<deepface_rs::detection::centerface::centerface::ModelRecordItem<burn_ndarray::backend::NdArray<f32,i64,i8>,burn_core::record::settings::FullPrecisionSettings>,burn_ndarray::backend::NdArray<f32,i64,i8> >,tuple{{content}}lt;>,bincode::de::decoder::DecoderImpl<bincode::de::read::SliceReader,bincode::config::Configuration<bincode::config::LittleEndian,bincode::config::Varint,bincode::config::NoLimit>,tuple{{content}}lt;> > >(struct bincode::de::decoder::DecoderImpl<bincode::de::read::SliceReader,bincode::config::Configuration<bincode::config::LittleEndian,bincode::config::Varint,bincode::config::NoLimit>,tuple{{content}}lt;> > *)
bincode::borrow_decode_from_slice_with_context
bincode::borrow_decode_from_slice
<burn_core::record::memory::BinBytesRecorder<S> as burn_core::record::recorder::Recorder<B>>::load_item 
burn_core::record::recorder::Recorder::load 
struct deepface_rs::detection::centerface::centerface::Model<burn_ndarray::backend::NdArray<f32,i64,i8> > deepface_rs::detection::centerface::centerface::Model<burn_ndarray::backend::NdArray<f32,i64,i8> >::from_embedded<burn_ndarray::backend::NdArray<f32,i64,i8> >() 
struct deepface_rs::detection::centerface::centerface::Model<burn_ndarray::backend::NdArray<f32,i64,i8> > deepface_rs::detection::centerface::centerface::impl$0::default<burn_ndarray::backend::NdArray<f32,i64,i8> >()
struct deepface_rs::detection::centerface::CenterFace deepface_rs::detection::centerface::CenterFace::new()
static void basic::main() 
void core::ops::function::FnOnce::call_once<void (*)(),tuple{{content}}lt;> >( *) 
void std::sys::backtrace::__rust_begin_short_backtrace<void (*)(),tuple{{content}}lt;> >( *) 
int std::rt::lang_start::closure$0<tuple{{content}}lt;> >(struct std::rt::lang_start::closure_env$0<tuple{{content}}lt;> > *) 
void std::rt::lang_start_internal() (@std::rt::lang_start_internal:42)
__int64 std::rt::lang_start<tuple{{content}}lt;> >( *, __int64, unsigned char * *, unsigned char) 
main (@main:9)

Conclusion

In conclusion, the stack overflow issue occurs when loading a model imported from ONNX using the burn-import generated code. The issue is caused by a recursive function call that leads to a stack overflow. To fix the issue, we need to modify the burn-import generated code to avoid the recursive function call.

Recommendations

To fix the issue, we recommend the following:

  1. Modify the burn-import generated code to avoid the recursive function call.
  2. Use a different approach to load the model, such as using a different library or framework.
  3. Test the code thoroughly to ensure that the issue is fixed.

Future Work

In the future, we plan to:

  1. Investigate the cause of the stack overflow issue and provide a more detailed explanation.
  2. Provide a patch or a fix for the issue.
  3. Test the code thoroughly to ensure that the issue is fixed.

Acknowledgments

Q: What is the cause of the stack overflow issue when loading a model imported from ONNX?

A: The stack overflow issue is caused by a recursive function call in the burn-import generated code. The from_file function calls the load function, which in turn calls the load_record function, leading to a recursive function call that causes a stack overflow.

Q: How can I reproduce the issue?

A: To reproduce the issue, follow these steps:

  1. Download the ONNX model from the GitHub repository: https://github.com/Star-Clouds/CenterFace/raw/master/models/onnx/centerface.onnx
  2. Import the model using the following code:
ModelGen::new()
    .input("models/detection/centerface.onnx")
    .out_dir("models/detection")
    .record_type(RecordType::Bincode)
    .embed_states(false)
    .run_from_script();
  1. Load the model using the following code:
mod centerface {
    include!(concat!(env!("OUT_DIR"), "/models/detection/centerface.rs"));
}
let model: centerface::Model<Backend> = centerface::Model::default();

Q: What is the expected behavior when loading a model imported from ONNX?

A: The expected behavior is that the model is loaded successfully without any errors.

Q: What are the possible solutions to fix the stack overflow issue?

A: The possible solutions to fix the stack overflow issue are:

  1. Modify the burn-import generated code to avoid the recursive function call.
  2. Use a different approach to load the model, such as using a different library or framework.
  3. Test the code thoroughly to ensure that the issue is fixed.

Q: How can I test the code to ensure that the issue is fixed?

A: To test the code, follow these steps:

  1. Modify the burn-import generated code to avoid the recursive function call.
  2. Use a different approach to load the model, such as using a different library or framework.
  3. Test the code thoroughly to ensure that the issue is fixed.

Q: What are the future plans to fix the stack overflow issue?

A: The future plans to fix the stack overflow issue are:

  1. Investigate the cause of the stack overflow issue and provide a more detailed explanation.
  2. Provide a patch or a fix for the issue.
  3. Test the code thoroughly to ensure that the issue is fixed.

Q: How can I get help if I encounter the stack overflow issue?

A: If you encounter the stack overflow issue, you can get help by:

  1. Checking the documentation and tutorials for the burn-import library.
  2. Searching online for solutions to the issue.
  3. Reaching out to the community for help.
  4. Contacting the maintainers of the burn-import library for assistance.

Q: What are the best practices to avoid the stack overflow issue?

A: The best practices to avoid the stack overflow issue:

  1. Use a different approach to load the model, such as using a different library or framework.
  2. Test the code thoroughly to ensure that the issue is fixed.
  3. Avoid using recursive function calls.
  4. Use a debugger to identify the cause of the issue.

Q: How can I contribute to the burn-import library to fix the stack overflow issue?

A: If you want to contribute to the burn-import library to fix the stack overflow issue, you can:

  1. Fork the repository and create a new branch.
  2. Modify the burn-import generated code to avoid the recursive function call.
  3. Test the code thoroughly to ensure that the issue is fixed.
  4. Submit a pull request to the maintainers of the burn-import library.