View Source Changelog
v0.4.0-rc2 (2026-08-19)
Browse the Repository | Released Assets
Bug fixes only, no new API. Three of these interlock: a build that fails without saying so produces an empty interpreter, a guard that was supposed to reject empty interpreters waves it through, and the next accessor call takes the VM down with it. None of the three needs anything unusual to reach.
Changed
tflite_beam_interpreter_builder:build/2returns{error, Reason}when the build fails. It returnedokunconditionally and discarded the status TFLite handed it, so a model that could not be built reported success and left an empty interpreter behind. Code that matchedok = build(...)on a model that was quietly failing will now fail at that match, which is the point.In
tflite_elixirthis reachesTFLiteElixir.InterpreterBuilder.build!/2, which starts raising throughdeferrorwhere callers used to meet aMatchErrorfurther down. That suite has no negative test forbuild/2-- every call site in it is a happy path -- so nothing there will notice the difference.
Fixed
Reaching into an interpreter that a failed
build/2had emptied killed the VM with SIGSEGV. Every resource accessor set an error term when it found a null value and then returned the resource anyway, while every caller tests only the returned pointer, so the guard passed and the next line dereferenced null. All eight of them now return nothing, and the calls that used to crash return{error, Reason}.build/2no longer leaves previously fetched tensors pointing into freed memory. TFLite destroys the interpreter it is building into on the way in -- before it can fail, so this applies to failed builds too -- but the tensor handles cached bytflite_beam_interpreter:tensor/2were never cleared. Fetching a tensor and then building again was a use-after-free.Tensor handles now report that their interpreter has gone instead of reading freed memory. The interpreter marked each cached tensor when it was torn down, but nothing ever read that mark: all six NIFs taking a tensor checked only that its pointer was non-null, which a dangling pointer is.
This is visible in one more place than the two above: a handle does not keep its interpreter alive, so reading through one whose interpreter has already been collected now returns
{error, Reason}' where it used to return whatever was left in the freed memory. Keep the interpreter reachable for as long as its tensors are in use -- which is what the code doing this correctly already does, or it would have been crashing. ### Added - A test suite,rebar3 ct, covering model loading, the builder, interpreters, tensors, invocation and signature runners, along with the failure cases above. It runs in CI on Linux x86_64 and macOS arm64. The four model fixtures it uses come from TensorFlow's own testdata and live intest/, which is not part of the published package. ## v0.4.0-rc1 (2026-08-19) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.4.0-rc1) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.4.0-rc1) A release candidate. Everything here is new surface rather than changed behaviour, but it is a lot of it at once, so it is worth a look before it becomes 0.4.0. Depend on it explicitly -- a pre-release is not picked up by a requirement like"~> 0.3". ### Added - Signature runners. A model's signatures could be listed withinterpreter:signaturekeys/1andget_signature_defs/1, but there was no way to run one, so tensors still had to be addressed by index and the order of a model's outputs guessed at.tflite_beam_interpreter:get_signature_runner/2now returns a runner, andtflite_beam_signature_runnerdrives it: names and counts of its inputs and outputs, reading and writing them by name, resizing them, allocating, invoking and cancelling. Passingnilas the key asks for the primary subgraph, which works on models that declare no signatures at all, so this is usable with older exports too. A runner belongs to the interpreter that handed it out and holds a reference to it, so it stays usable even after the interpreter's own term is collected. Like the interpreter it is not safe to use from several processes at once. -tflite_beam_interpreter:enable_cancellation/1andcancel/1. An invocation runs on a dirty scheduler and could not be interrupted;cancel/1does not block and is safe to call from another process, so a long inference can now be given up on. Withoutenable_cancellation/1beforehand, cancelling is an error. -tflite_beam_interpreter:release_non_persistent_memory/1, which hands back the memory that is only needed while invoking. Invoking again reallocates it, trading time for memory on devices short of the latter. -tflite_beam_interpreter:reset_variable_tensors/1, resetting all of a model's variable tensors. Only a single-tensor version existed. -tflite_beam_interpreter:get_allow_fp16_precision_for_fp32/1andset_allow_fp16_precision_for_fp32/2. -tflite_beam_interpreter:signature_inputs/2,signature_outputs/2,get_subgraph_index_from_signature/2andsubgraphs_size/1, which describe a model's signatures and subgraphs without having to build a runner. -tflite_beam_interpreter:resize_input_tensor/3andresize_input_tensor_strict/3. Input shapes could not be changed at all before, so a model with a variable dimension could only ever be fed whatever shape it was exported with. Callallocate_tensors/1again afterwards. The strict variant only touches dimensions the model left unknown. -tflite_beam_flatbuffer_model:verify_and_build_from_buffer/1,2. A verifying counterpart existed for files but not for buffers, so a model already in memory could only be built unchecked. ### Fixed - Theminimum_runtimefield of thetflite_beam_flatbuffer_modelrecord held a boolean. Three of the four places that fill the record askedflatbuffer_model_initializedfor it, so anyone reading the field to decide whether a runtime is new enough was readingtrue. - Building a model from a buffer no longer leaks the copy of that buffer when the model turns out not to parse. ## v0.3.12 (2026-08-19) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.12) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.12) ### Fixed - Interpreters, interpreter builders and the resources they borrow (the op resolver and the flatbuffer model) now hold real references to each other. Previously only a hand-rolled counter recorded the link, so the VM was free to collect a resource that was still in use, and the destructor's decrement landed in whatever resource had been given that memory next. On arm64 this brought down the emulator with SIGBUS. - Resources are no longer read uninitialised.enif_alloc_resourcehands back raw memory, so fields that looked initialised in the struct definition were not, andNifResTfLiteTensorcould reachdeleteon a wild pointer. - Everytflite::FlatBufferModeland everytflite::Interpreterwas leaked; both are now released with the resource that owns them. - Creating an Edge TPU interpreter no longer leaks its resource when the interpreter cannot be built or its tensors cannot be allocated. - Tensor resources are no longer leaked. Each one was created with a reference that nobody ever gave back, on top of the one the interpreter's cache holds, so none of them could be freed. Failing partway through reading a tensor leaked one as well. - Edge TPU context resources are no longer leaked, for the same reason: the reference fromenif_alloc_resourcewas never released. -allocate_tensorsno longer reportsunknown errorfor three of the statuses TFLite can return. A model carrying ops the interpreter cannot resolve -- an Edge TPU model given to a plain builtin resolver, say -- now saysUnresolvedOpsinstead. The mapping lived in two places, one of which had drifted; there is now only one. - The Edge TPU itself is handed back when nothing is using it any more. Contexts were parked in a global map that was written to and never read, purely so theirshared_ptrcould not run out, which held the device until the VM exited. Each context resource now owns its share directly, and an Edge TPU interpreter holds a reference to the context it delegates to, so the device outlives every interpreter built on it and is released once the last one is gone. ## v0.3.11 (2026-08-15) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.11) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.11) ### Fixed - Platform-specific binaries now go to the consuming app's_build/<target><env>/lib/tflitebeam/privinstead ofdeps/tflitebeam/priv, so switchingMIX_TARGETno longer picks up another target'stflite_beam.so.rm -rf deps/tflite_beamis no longer needed when cross-compiling ([#73](https://github.com/cocoa-xu/tflite_beam/issues/73)). - Building from source no longer fails on hosts that have gflags installed system-wide (e.g.brew install gflags). glog resolved gflags throughfind_package, which picked up the system copy and collided with the targets the bundled gflags had already defined. ## v0.3.10 (2026-06-30) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.10) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.10) ### Changed - [deps] Use libedgetpu v0.1.14. - Use tensorflow v2.21.0. ## v0.3.9 (2025-04-03) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.9) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.9) ### Changed - [deps] Use libedgetpu v0.1.12. - Use tensorflow v2.19.0. ## v0.3.8 (2025-02-10) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.8) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.8) ### Changed - [deps] Use libedgetpu v0.1.10. - Use tensorflow v2.18.0. ## v0.3.7 (2024-09-03) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.7) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.7) ### Fixed - fixed project build directory ## v0.3.6 (2024-03-17) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.6) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.6) ### Changed - [deps] Use libedgetpu v0.1.9. - Use tensorflow v2.16.1. - Use libusb v1.0.27. - Use Erlang/OTP 25.x for precompiled binaries. This unified the required Erlang/OTP NIF version to2.16for precompiled binaries. - Detect and useHTTP_PROXY,HTTPS_PROXY,http_proxyandhttps_proxywhen fetch preocmpiled binary from GitHub. ## v0.3.5 (2024-01-24) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.5) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.5) ### Changed - Precompiled version for armv6 devices. - RemovedTFBEAM_XNNPACK_ENABLE_ARM_I8MMoption as it should work as long as a newer C compiler is used. - Updated metadata_schema to 1.5.0 ## v0.3.4 (2024-01-23) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.4) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.4) ### Changed - [deps] Use libedgetpu v0.1.8. - Use tensorflow v2.15.0. ## v0.3.3 (2023-07-21) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.3) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.3) ### Changed - [deps] Use libedgetpu v0.1.7. - Use tensorflow v2.13.0. ## v0.3.2 (2023-04-03) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.2) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.2) ### Fixed - [precompiled-nerves] Guess correctTARGET_ARCHfromTARGET_CPU. ## v0.3.1 (2023-04-03) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.1) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.1) ### Fixed - [deps] Use libedgetpu v0.1.6. ### Changed - [examples] Examples moved to [cocoa-xu/tflite_elixir](https://github.com/cocoa-xu/tflite_elixir). ## v0.3.0 (2023-04-02) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.3.0) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.3.0) ### Breaking Change - This repo will now be the TensorFlow Lite Erlang bindings. For Elixir bindings, please visit [cocoa-xu/tflite_elixir](https://github.com/cocoa-xu/tflite_elixir). ### Fixed - [erlang] Generate correct error message from a list of errors. - [c_src] Initialize resource pointers withnullptr. - Implemented tokenizers for MobileBERT (#57) by @cocoa-xu. - [make] Ensure priv dir exist. ## v0.2.1 (2023-04-02) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.2.1) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.2.1) ### Changed - [deps] Use TensorFlow Lite version 2.11.1. ### Fixed - [erlang] Generate correct error message from a list of errors. - [c_src] Initialize resource pointers withnullptr. - Implemented tokenizers for MobileBERT (#57) by @cocoa-xu. - [make] Ensure priv dir exist. ## v0.2.0 (2023-03-30) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.2.0) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.2.0) ### Breaking Changes - Renamed root namespace fromTFLiteElixirtoTFLiteBEAM### Changes -bufferwill be copied and managed when usingTFLiteBEAM.FlatBufferModel.build_from_buffer/1. -TFLiteBEAM.TFLiteTensor.dims/1returns a list (following TensorFlow Lite's C++ API convention) whileTFLiteBEAM.TFLiteTensor.shape/1returns a tuple (folllowingnx's convention.) ### Added - Erlang support. - [example] added pose estimation example (#43) by @mnishiguchi - [example] use thunder model instead of lightning in pose estimation (#45) by @mnishiguchi - [example] added audio classification example - Experimental high-level moduleTFLiteBEAM.ImageClassification. ```elixir iex> alias TFLiteBEAM.ImageClassification iex> {:ok, pid} = ImageClassification.start("test/test_data/mobilenet_v2_1.0_224_inat_bird_quant.tflite") iex> ImageClassification.predict(pid, "test/test_data/parrot.jpeg") %{class_id: 923, score: 0.70703125} iex> ImageClassification.set_label_from_associated_file(pid, "inat_bird_labels.txt") :ok iex> ImageClassification.predict(pid, "test/test_data/parrot.jpeg") %{class_id: 923, label: "Ara macao (Scarlet Macaw)", score: 0.70703125} iex> ImageClassification.predict(pid, "test/test_data/parrot.jpeg", top_k: 3) [ %{class_id: 923, label: "Ara macao (Scarlet Macaw)", score: 0.70703125}, %{ class_id: 837, label: "Platycercus elegans (Crimson Rosella)", score: 0.078125 }, %{ class_id: 245, label: "Coracias caudatus (Lilac-breasted Roller)", score: 0.01953125 } ] ``` ## v0.1.7 (2023-03-22) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.1.7) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.1.7) ### Breaking Changes - DeprecatedTFLiteElixir.Interpreter.allocate_tensors!/1- Deprecated Access behaviour forTFLiteElixir.FlatBufferModel### Fixed - Properly implementedTFLiteElixir.FlatBufferModel.read_all_metadata/1`. ```elixir iex> filename = Path.join([__DIR, "test", "test_data", "mobilenet_v2_1.0_224_inat_bird_quant.tflite"]) iex> %FlatBufferModel{} = model = FlatBufferModel.build_from_buffer(File.read!(filename)) iex> TFLiteElixir.FlatBufferModel.read_all_metadata(model) %{ TFLITE_METADATA: %{ description: "Identify the most prominent object in the image from a known set of categories.", min_parser_version: "1.0.0", name: "ImageClassifier", subgraph_metadata: [ %{ input_tensor_metadata: [ %{ content: %{ content_properties: %{color_space: "RGB"}, content_properties_type: "ImageProperties" }, description: "Input image to be classified.", name: "image", process_units: [ %{ options: %{mean: [127.5], std: [127.5]}, options_type: "NormalizationOptions" } ], stats: %{max: [255.0], min: [0.0]} } ], output_tensor_metadata: [ %{ associated_files: [ %{ description: "Labels for categories that the model can recognize.", name: "inat_bird_labels.txt", type: "TENSOR_AXIS_LABELS" } ], description: "Probabilities of the labels respectively.", name: "probability", stats: %{max: [255.0], min: [0.0]} } ] } ] }, min_runtime_version: "1.5.0" }`` ### Changed - ImproveTFLiteElixir.TFLiteTensor.to_nx/2(#33) by @cocoa-xu - [doc] Improve doc for to_nx (#31) by @mnishiguchi ### Added - Implemented -FlatBufferModel.{list_associated_files/1,get_associated_file/2}-TFLiteElixir.Interpreter.signature_keys/1-TFLiteElixir.Interpreter.execution_plan/1-TFLiteElixir.Interpreter.new_from_buffer/1-TFLiteElixir.Interpreter.tensors_size/1-TFLiteElixir.Interpreter.variables/1-TFLiteElixir.Interpreter.set_variables/2-TFLiteElixir.Interpreter.set_inputs/2-TFLiteElixir.Interpreter.set_outputs/2- [example] object detection example (#40) by @mnishiguchi ## v0.1.6 (2023-03-19) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.1.6) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.1.6) ### Fixed - [edgetpu] Improved edgetpu context handling, and bumped libedgetpu_runtime_version to v0.1.5. Fixed [#30](https://github.com/cocoa-xu/tflite_beam/issues/30) ### Added - [example] artistic-style-transfer example (#27) @mnishiguchi ## v0.1.5 (2023-03-18) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.1.5) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.1.5) ### Breaking Changes - Deprecated functions: -TFLiteElixir.FlatBufferModel.initialized!/1-TFLiteElixir.FlatBufferModel.get_minimum_runtime!/1-TFLiteElixir.TFLiteTensor.tensor!-TFLiteElixir.TFLiteTensor.to_nx!-TFLiteElixir.TFLiteTensor.to_binary!-TFLiteElixir.FlatBufferModel.build_from_buffer!-TFLiteElixir.FlatBufferModel.get_full_signature_list-TFLiteElixir.Coral.get_edge_tpu_context/1now takes keyword options. ### Changes - [example] Improve Inference on TPU notebook (#15) @mnishiguchi - [example] Improve Inference on TPU notebook (#16) @mnishiguchi - Alias modules in tflite_interpreter (#17) @mnishiguchi - Rename elixir files based on module names (#18) @mnishiguchi - add moduledocs (#19) @mnishiguchi ### Fixed - Fixed a few places that could lead to segmentation fault. - [example] Fixed broken ESRGAN link, Visualize the result section in the "Super Resolution" notebook. Lock downtflite_elixirandevisionversion (#29) @mnishiguchi. - [typespec] Fixed typespec forTFLiteElixir.Coral.edge_tpu_devices/0(#22) @mnishiguchi. ### Added - [test] Unit tests forTFLiteElixir.Interpreter,TFLiteElixir.InterpreterBuilderandTFLiteElixir.Ops.Builtin.BuiltinResolver. - [example] Added intro text to super_resolution_example. (#26) @mnishiguchi. -TFLiteElixir.FlatBufferModel.error_reporter/1. -TFLiteElixir.FlatBufferModel.verify_and_build_from_file/2## v0.1.4 (2023-03-14) [Browse the Repository](https://github.com/cocoa-xu/tflite_beam/tree/v0.1.4) | [Released Assets](https://github.com/cocoa-xu/tflite_beam/releases/tag/v0.1.4) ### Breaking Changes - Snake case functions (#21) @mnishiguchi ### Changes - [example] Improve Inference on TPU notebook (#15) @mnishiguchi - [example] Improve Inference on TPU notebook (#16) @mnishiguchi - Alias modules in tflite_interpreter (#17) @mnishiguchi - Rename elixir files based on module names (#18) @mnishiguchi - add moduledocs (#19) @mnishiguchi ### Fixed - Fix compilation logic when not using precompiled binaries. ### Added - ImplementedTFLiteElixir.reset_variable_tensor/1. - Add support for armv6. ### Misc - Simple workaround for cortex-a53 and cortex-a57,vcvtaq_s32_f32`. ## v0.1.3 (2023-03-09) Browse the Repository | Released Assets ### Changes - Bump TFLite version to v2.11.0. ## v0.1.2 (2023-03-08) Browse the Repository | Released Assets First release on hex.pm.