PyInstaller+Tensorflow+Sonnet

I’m having issues building tensorflow+sonnet applications with pyinstaller. I’ve built keras ones fine, but sonnet ones have an issue as below.

Sonnet doesn’t seem to work with pyinstaller. This can be reproduced with a very simple example as below:

import sonnet
print(“Hello world”)

I used a spec file:

-- mode: python ; coding: utf-8 --

The following fixes a different pyinstaller issue due to recursion

import sys
sys.setrecursionlimit(5000)

block_cipher = None

a = Analysis([‘pi_test.py’],
pathex=[‘c:\Software\ICServer\ICServer-src\Python\GraphNet\minimal_pyinstaller_test’],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name=‘pi_test’,
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name=‘pi_test’)

The error is:

2021-11-08 19:42:43.507236: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library cudart64_110.dll
Traceback (most recent call last):
File “site-packages\tensorflow\python\autograph\pyct\parser.py”, line 150, in parse_entity
File “site-packages\tensorflow\python\autograph\pyct\inspect_utils.py”, line 147, in getimmediatesource
File “inspect.py”, line 798, in findsource
OSError: could not get source code

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “site-packages\tensorflow\python\autograph\impl\api.py”, line 749, in to_graph
File “site-packages\tensorflow\python\autograph\impl\api.py”, line 284, in _convert_actual
File “site-packages\tensorflow\python\autograph\pyct\transpiler.py”, line 286, in transform
File “site-packages\tensorflow\python\autograph\pyct\transpiler.py”, line 470, in transform_function
File “site-packages\tensorflow\python\autograph\pyct\transpiler.py”, line 346, in transform_function
File “site-packages\tensorflow\python\autograph\pyct\parser.py”, line 152, in parse_entity
ValueError: Unable to locate the source code of <function BaseBatchNorm.call at 0x000002BF2C3C84C0>. Note that functions defined in certain environments, like the interactive Python shell do not expose their source code. If that is the case, you should to define them in a .py source file. If you are certain the code is graph-compatible, wrap the call using @tf.autograph.do_not_convert. Original error: could not get source code

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “C:\Software\ICServer\ICServer-src\Python\GraphNet\minimal_pyinstaller_test2\pi_test.py”, line 1, in
import sonnet
File “”, line 991, in _find_and_load
File “”, line 975, in _find_and_load_unlocked
File “”, line 671, in load_unlocked
File “c:\python38\lib\site-packages\PyInstaller\loader\pyimod03_importers.py”, line 623, in exec_module
exec(bytecode, module.dict)
File "site-packages\sonnet_init
.py", line 21, in
File “”, line 991, in _find_and_load
File “”, line 975, in _find_and_load_unlocked
File “”, line 671, in _load_unlocked
File “c:\python38\lib\site-packages\PyInstaller\loader\pyimod03_importers.py”, line 623, in exec_module
exec(bytecode, module.dict)
File “site-packages\sonnet\distribute.py”, line 21, in
File “”, line 991, in _find_and_load
File “”, line 975, in _find_and_load_unlocked
File “”, line 671, in _load_unlocked
File “c:\python38\lib\site-packages\PyInstaller\loader\pyimod03_importers.py”, line 623, in exec_module
exec(bytecode, module.dict)
File “site-packages\sonnet\src\distribute\batch_norm.py”, line 22, in
File “”, line 991, in _find_and_load
File “”, line 975, in _find_and_load_unlocked
File “”, line 671, in _load_unlocked
File “c:\python38\lib\site-packages\PyInstaller\loader\pyimod03_importers.py”, line 623, in exec_module
exec(bytecode, module.dict)
File “site-packages\sonnet\src\batch_norm.py”, line 34, in
File “site-packages\sonnet\src\batch_norm.py”, line 132, in BaseBatchNorm
File “site-packages\sonnet\src\utils.py”, line 180, in smart_autograph
File “site-packages\tensorflow\python\autograph\impl\api.py”, line 752, in to_graph
tensorflow.python.autograph.impl.api.ConversionError: converting <function BaseBatchNorm.call at 0x000002BF2C3C84C0>: ValueError: Unable to locate the source code of <function BaseBatchNorm.call at 0x000001EE45EA81F0>. Note that functions defined in certain environments, like the interactive Python shell do not expose their source code. If that is the case, you should to define them in a .py source file. If you are certain the code is graph-compatible, wrap the call using @tf.autograph.do_not_convert. Original error: could not get source code

I reported this to the sonnet developers and the closed the issue straight away saying it wasn’t their problem and I should report it to tensorflow developers

Sonnet is written in pure python, and the method in question (in src/batch_norm.py) is decorated with @utils.smart_autograph. Can anyone suggest how to get this working?

Thanks

Derek

Is this a gast version issue?

The gast error looks like a historic thing (and not quite the same error) “On TensorFlow 2.2 or higher, the gast bug has been fixed and gast 0.3+ would be required.”. I’m using tensorflow 2.4 and gast 0.3.3. If I attempt to update gast to the latest version it breaks tensorflow even from the python interpreter.

The error I see is only with pyinstaller, and relates to autograph not being able to access the BaseBatchNorm call (or possibly code within this?) method once packaged.

1 Like

Have you tried to use the pyinstaller Tensorflow hooks with a supported version?

Thanks, I got it working with that hook. Two futher changes were also required:

i) I had to change the line in the hook:

datas = collect_data_files('tensorflow', excludes=data_excludes)

to:
datas = collect_data_files(‘tensorflow’)

as excludes dosn’t seem to be in the API (at least for versions I have Python: 3.8.3, Pyinstaller 3.6)

ii) I had to add the following import to my python file:

import tensorflow.python.keras.engine.base_layer_v1

Thanks a lot!

D.