tfjs icon indicating copy to clipboard operation
tfjs copied to clipboard

tfjs-node compatibility question

Open Mattk70 opened this issue 9 months ago • 3 comments

This is a question, and

  1. A request for clearer documentation
  2. Possibly, a request for updated bindings in tfjs-node

System information

  • TensorFlow.js version (you are using): 4.22.0
  • Are you willing to contribute it (Yes/No): Not unwilling, just incapable, I'm afraid!

Describe the feature and the current behavior/state.

I see this error when trying to use tf.node.loadSavedModel() on a model saved using Tensorflow version 2.15.x

Failed to load SavedModel: Converting GraphDef to Graph has failed with an error: 'Op type not registered 'DisableCopyOnRead' in binary running on...

There are various posts on Stack Overflow and elsewhere suggesting this is due to incompatible versions of Tensorflow.

I've done an extensive search for details of tfjs-node compatibility with Tensorflow versions, but haven't found anything. However, stepping through the code in Chrome devtools, I saw that the tfjs-node TF_Version variable had a value of 2.9.1.

Is it the case that tfjs-node is built with Tensorflow 2.9.1 bindings, and therefore may be incompatible with models using features introduced since then?

Will this change the current api? How?

I have no idea.

Who will benefit with this feature?

I guess, anyone wanting to load a tensorflow model built with features introduced in the last 9 versions of tensorflow?

Any Other info.

I may be entirely on the wrong track. If so, it would be good to know. If not, is there a roadmap or plan to update the tfjs-node bindings?

Many thanks in advance!

Mattk70 avatar Mar 11 '25 18:03 Mattk70

Hi @Mattk70 ,

Could you please provide a small, reproducible code snippet so I can also check it on my end? The error suggests that a TensorFlow custom operation is missing. Please check the TFJS operation registry.

Thank you.

shmishra99 avatar Mar 21 '25 08:03 shmishra99

Hi - thanks for your reply! OK, so I will try to create a minimal demonstration. I started this test with tensorflow 2.16.1, Python 3.12. All tests were run on Windows11, using Python venv.

model.py


import tensorflow as tf

# Import EfficientNetV2B0 - use default parameters
model = tf.keras.applications.EfficientNetV2B0(
    include_top=True,
    weights='imagenet',
    input_tensor=None,
    input_shape=None,
    pooling=None,
    classes=1000,
    classifier_activation='softmax',
    include_preprocessing=True
)

# Save the model
model.export("./test")

main.js

const tf = require('@tensorflow/tfjs-node')

const model = "test";

const test = (async () => {
     await tf.node.loadSavedModel(model, ['serve'], 'serving_default')
          .catch(e => console.error('Model failed to load!', e));        
})();

package.json

{
  "name": "tfjs-node-test",
  "version": "1.0.0",
  "description": "Test showing failing model load",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@tensorflow/tfjs-node": "4.22.0"
  }
}

If I load/save the model using model.py, then run node main.js I get the same error:

2025-03-22 09:54:48.289440: I tensorflow/cc/saved_model/reader.cc:43] Reading SavedModel from: test
2025-03-22 09:54:48.306611: I tensorflow/cc/saved_model/reader.cc:81] Reading meta graph with tags { serve }
2025-03-22 09:54:48.306733: I tensorflow/cc/saved_model/reader.cc:122] Reading SavedModel debug info (if present) from: test
2025-03-22 09:54:48.376202: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:354] MLIR V1 optimization pass is not enabled
2025-03-22 09:54:48.398325: I tensorflow/cc/saved_model/loader.cc:228] Restoring SavedModel bundle.
2025-03-22 09:54:48.535596: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:903] tfg_optimizer{} failed: NOT_FOUND: Op type not registered 'DisableCopyOnRead' in binary running on MATTS-ML-PC. Make
 sure the Op and Kernel are registered in the binary running in this process. Note that if you are loading a saved graph which used ops from tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be do
ne before importing the graph, as contrib ops are lazily registered when the module is first accessed.
        While importing FunctionDef: __inference__traced_save_17505
        when importing GraphDef to MLIR module in GrapplerHook
2025-03-22 09:54:48.975383: E tensorflow/core/framework/node_def_util.cc:630] NodeDef mentions attribute debug_name which is not in the op definition: Op<name=VarHandleOp; signature= -> resource:resource; 
attr=container:string,default=""; attr=shared_name:string,default=""; attr=dtype:type; attr=shape:shape; attr=allowed_devices:list(string),default=[]; is_stateful=true> This may be expected if your graph g
enerating binary is newer  than this binary. Unknown attributes will be ignored. NodeDef: {{node Variable}}
2025-03-22 09:54:49.046888: I tensorflow/cc/saved_model/loader.cc:212] Running initialization op on SavedModel bundle at path: test
2025-03-22 09:54:49.161143: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:903] tfg_optimizer{} failed: NOT_FOUND: Op type not registered 'DisableCopyOnRead' in binary running on [PC NAME REDACTED]. Make
 sure the Op and Kernel are registered in the binary running in this process. Note that if you are loading a saved graph which used ops from tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be do
ne before importing the graph, as contrib ops are lazily registered when the module is first accessed.
        While importing FunctionDef: __inference__traced_save_17505
        when importing GraphDef to MLIR module in GrapplerHook
2025-03-22 09:54:49.225560: I tensorflow/cc/saved_model/loader.cc:301] SavedModel load for tags { serve }; Status: success: OK. Took 936102 microseconds.
Model failed to load! Error: Failed to load SavedModel: Converting GraphDef to Graph has failed with an error: 'Op type not registered 'DisableCopyOnRead' in binary running on [PC NAME REDACTED]. Make sure the Op
 and Kernel are registered in the binary running in this process. Note that if you are loading a saved graph which used ops from tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be done before im
porting the graph, as contrib ops are lazily registered when the module is first accessed.' The binary trying to impor
    at NodeJSKernelBackend.loadSavedModelMetaGraph (C:\Users\simpo\PycharmProjects\tfjs-node-test\node_modules\@tensorflow\tfjs-node\dist\nodejs_kernel_backend.js:435:29)
    at Object.<anonymous> (C:\Users\simpo\PycharmProjects\tfjs-node-test\node_modules\@tensorflow\tfjs-node\dist\saved_model.js:448:45)
    at step (C:\Users\simpo\PycharmProjects\tfjs-node-test\node_modules\@tensorflow\tfjs-node\dist\saved_model.js:49:23)
    at Object.next (C:\Users\simpo\PycharmProjects\tfjs-node-test\node_modules\@tensorflow\tfjs-node\dist\saved_model.js:30:53)
    at fulfilled (C:\Users\simpo\PycharmProjects\tfjs-node-test\node_modules\@tensorflow\tfjs-node\dist\saved_model.js:21:58)

I repeated this with tensorflow 2.12 and Python 3.10, with the same error: 'Op type not registered 'DisableCopyOnRead'.

I then changed model.py to use model.save() instead of model.export() and ran the process again. I got the same error.

Finally, I changed to tensorflow 2.9.1 / Python 3.10 and it succeeded.

Mattk70 avatar Mar 22 '25 11:03 Mattk70

@shmishra99 - can you offer any guidance?

Mattk70 avatar Apr 21 '25 08:04 Mattk70