FS#71919 - [python-tensorflow] Needs standalone keras package in some cases

Attached to Project: Community Packages
Opened by Chih-Hsuan Yen (yan12125) - Wednesday, 25 August 2021, 09:39 GMT
Last edited by Konstantin Gizdov (kgizdov) - Monday, 30 August 2021, 10:48 GMT
Task Type Bug Report
Category Packages
Status Closed
Assigned To Sven-Hendrik Haase (Svenstaro)
Konstantin Gizdov (kgizdov)
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Description:

For Tensorflow 2.6, somehow the keras package is needed in some cases:

$ python -c 'from tensorflow.compat.v1.nn.rnn_cell import BasicLSTMCell'
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.

$ python -c 'import tensorflow; tensorflow.compat.v1.nn.rnn_cell.BasicLSTMCell'
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.compat.v2.summary API due to missing TensorBoard installation.
WARNING:root:Limited tf.summary API due to missing TensorBoard installation.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.9/site-packages/tensorflow/python/util/lazy_loader.py", line 62, in __getattr__
module = self._load()
File "/usr/lib/python3.9/site-packages/tensorflow/python/util/lazy_loader.py", line 45, in _load
module = importlib.import_module(self.__name__)
File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 984, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'keras'

The second way appears in tests of my AUR package python-tf2onnx: https://github.com/onnx/tensorflow-onnx/blob/v1.9.2/tests/test_seq2seq.py#L16. I suspect it is not a common practice, but still a valid way.

If I create a package python-keras 2.6.0, both ways work. I attached a proof-of-concept PKGBUILD based on the (out-dated) AUR package python-keras. It requires some cleanups, though (dependencies, ...)

Additional info:
python-tensorflow 2.6.0-2

Steps to reproduce:
1. Upgrade python-tensorflow to 2.6.0-2
2. Make sure keras is not installed (ex: `pip show keras` reports a warning)
3. Try to import RNN cells as described above
   PKGBUILD (1.2 KiB)
This task depends upon

Closed by  Konstantin Gizdov (kgizdov)
Monday, 30 August 2021, 10:48 GMT
Reason for closing:  Fixed
Additional comments about closing:  tensorflow 2.6.0-3
Comment by Chih-Hsuan Yen (yan12125) - Wednesday, 25 August 2021, 09:54 GMT
Also, if you wish, I'm willing to (co-)maintain community/python-keras after cleaning up PKGBUILD attached above.
Comment by Konstantin Gizdov (kgizdov) - Wednesday, 25 August 2021, 09:57 GMT
According to the official docs, keras as a separate package should have been deprecated. So I'd like some time to investigate.
Comment by Konstantin Gizdov (kgizdov) - Wednesday, 25 August 2021, 12:22 GMT
So after some testing, it kind of seems like this is an upstream bug. Which upstream, I am not sure. Firstly,
```
$ python -c 'from tensorflow.compat.v1.nn.rnn_cell import BasicLSTMCell; a = BasicLSTMCell; print(a)'
<class 'tensorflow.python.keras.layers.legacy_rnn.rnn_cell_impl.BasicLSTMCell'>
$ ls /usr/lib/python3.9/site-packages/tensorflow/python/keras/layers/legacy_rnn/rnn_cell_impl.py
/usr/lib/python3.9/site-packages/tensorflow/python/keras/layers/legacy_rnn/rnn_cell_impl.py
```
The module is installed correctly and available. What I think is happening is that the `lazy_loader.py` is failing when it does not get full module paths starting at package root. This could be a bug in the way LazyLoader is called or implemented, or it could be an incorrect usage to call it this way. If it succeeds when Keras is installed separately, that means LazyLoader just fails to recognise where the module should be located when called the second way and then looks inside the normal python package path rather than inside TensorFlow.

In any case, I do not see a reason to ship Keras as a separate package. Could we open a bug on both upstreams and let them give more background?
Comment by Chih-Hsuan Yen (yan12125) - Thursday, 26 August 2021, 01:36 GMT
> According to the official docs, keras as a separate package should have been deprecated.

Hmm, I saw something different. From release notes of Tensorflow 2.6, (https://github.com/tensorflow/tensorflow/releases/tag/v2.6.0)

> Keras been split into a separate PIP package (keras), and its code has been moved to the GitHub repository keras-team/keras. The API endpoints for tf.keras stay unchanged, but are now backed by the keras PIP package. The existing code in tensorflow/python/keras is a staled copy and will be removed in future release (2.7).

Mind to share a link for deprecation of Keras? Then I can ask for clarification from upstream devs.

> The module is installed correctly and available.

Yep that is indeed strange. I think your reasoning is likely.
Comment by Konstantin Gizdov (kgizdov) - Thursday, 26 August 2021, 10:44 GMT
You are correct. They have back-tracked in the last release of TF 2.6.0. I was referring to Keras 2.3.0 being announced as the last standalone release and the last supporting backends other than TF. Then it was all put in TF under `tf.keras` API. I guess they have changed their mind in TF 2.6.0. Thanks for digging this up. However, they still urge everyone to use the public API endpoints at `tf.keras` and remove any mention of `tensorflow.python.keras`. I guess that is indeed a bug upstream. I am guessing this is due to the `compat` path causing issues. Not sure. For this we have to ask upstream. Otherwise, I will make a `python-keras` package and push it to community as it seems to a hard dependency for Tensorflow from now on. You are welcome to co-maintain, but we'll have to make one either way haha :D
Comment by Chih-Hsuan Yen (yan12125) - Thursday, 26 August 2021, 12:52 GMT
Found this https://github.com/tensorflow/tensorflow/issues/51569. The traceback there is almost the same as mine. As the issue cannot be reproduced on Colab, the reporter closed the issue with "it is an arch package issue".

By the way, I noticed tensorflow 2.6 already declares keras as a dependency:

$ grep keras /usr/lib/python3.9/site-packages/tensorflow-2.6.0.dist-info/METADATA
Requires-Dist: keras-preprocessing
Requires-Dist: keras
Comment by Konstantin Gizdov (kgizdov) - Thursday, 26 August 2021, 13:08 GMT
Yes, it is an Arch packaging issue. :D We already agreed on that. `python-keras-2.6.0-1` is in [community]. I'm rebuilding tensorflow to reflect the changes, should be up in a few hours. ;)
However, I think calling tensorflow.compat is also not supported anymore (refer to TF 2.6.0 release notes).
Comment by Chih-Hsuan Yen (yan12125) - Friday, 27 August 2021, 01:49 GMT
Thanks you very much! I think this issue can be closed.

> However, I think calling tensorflow.compat is also not supported anymore (refer to TF 2.6.0 release notes).

Looks like some classes under tf.compat are deprecated, not the whole tf.compat namespace. Anyway, this is the issue for my AUR package tensorflow-onnx :)

Loading...