TL;博士:
我无法在我的 Colab 笔记本中将 GPT2 模型转换为 tflite。它会抛出错误,因为 causal_lm.generate()
函数不再适合(我认为)用 tf 具体函数包装,因为现在在文本生成后处理(以及可能的其他步骤)期间发生
.asnumpy()
转换。知道如何解决或规避这个问题吗?可能只是版本不兼容那么简单..
背景详情:
我的笔记本基于这个 google codelab 笔记本,它演示了将 GPT2 导出到 tflite。它从前到后运行没有问题。然而它已经过时了,并且不支持 GPU 运行。笔记本中使用的包的具体导入和版本是:
!pip install -q git+https://github.com/keras-team/keras-nlp.git@google-io-2023 tensorflow-text==2.12
import numpy as np
import keras_nlp
import tensorflow as tf
import tensorflow_datasets as tfds
import tensorflow_text as tf_text
from tensorflow import keras
from tensorflow.lite.python import interpreter
import time
from google.colab import files
print(tf.__version__)
print(keras.__version__)
print(keras_nlp.__version__)
2.12.1
2.12.0
0.5.0
我已修改导入如下(从顶部笔记本复制)以启用 GPU 支持。
!pip install keras_nlp
print(tf.__version__)
print(keras.__version__)
print(keras_nlp.__version__)
2.16.1
3.3.3
0.11.1
但是现在tflite 转换不起作用,抛出以下错误。尝试从 GPT2CausalLM 转换generate() 函数时发生错误。即使我绕过创建具体函数,它也会在转换模型本身时抛出错误..
# The generate() function from GPT2CausalLM is the actual function that does the magic. So you will convert it now. First, you wrap the generate() function into a TensorFlow concrete function.
@tf.function
def generate(prompt, max_length):
return gpt2_lm.generate(prompt, max_length)
concrete_func = generate.get_concrete_function(tf.TensorSpec([], tf.string), 100)
错误:
NotImplementedError Traceback (most recent call last)
[<ipython-input-10-d8866e8eac5d>](https://localhost:8080/#) in <cell line: 5>()
3 return gpt2_lm.generate(prompt, max_length)
4
----> 5 concrete_func = generate.get_concrete_function(tf.TensorSpec([], tf.string), 100)
27 frames
[/usr/local/lib/python3.10/dist-packages/tensorflow/python/framework/tensor.py](https://localhost:8080/#) in __array__(***failed resolving arguments***)
625 def __array__(self, dtype=None):
626 del dtype
--> 627 raise NotImplementedError(
628 f"Cannot convert a symbolic tf.Tensor ({self.name}) to a numpy array."
629 f" This error may indicate that you're trying to pass a Tensor to"
NotImplementedError: in user code:
File "<ipython-input-10-d8866e8eac5d>", line 3, in generate *
return gpt2_lm.generate(prompt, max_length)
File "/usr/local/lib/python3.10/dist-packages/keras_nlp/src/models/causal_lm.py", line 371, in postprocess *
return self.preprocessor.generate_postprocess(x)
File "/usr/local/lib/python3.10/dist-packages/keras_nlp/src/models/gpt2/gpt2_causal_lm_preprocessor.py", line 178, in generate_postprocess *
token_ids = ops.convert_to_numpy(token_ids)
File "/usr/local/lib/python3.10/dist-packages/keras/src/ops/core.py", line 512, in convert_to_numpy **
return backend.convert_to_numpy(x)
File "/usr/local/lib/python3.10/dist-packages/keras/src/backend/tensorflow/core.py", line 131, in convert_to_numpy
return np.asarray(x)
NotImplementedError: Cannot convert a symbolic tf.Tensor (StatefulPartitionedCall:1) to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported.
也发布在keras_nlp讨论论坛,但那里没有太多活动..
不兼容1:原笔记本无法使用GPU的原因是它尝试使用TF v 2.12.1,并且自从Google将CUDA从11.8升级到12.2后,tensorflow版本1< 2.15.0 simply do not recognise the GPU. []
我尝试将!apt update && apt install cuda-11-8
添加到原始 Google Codelab 笔记本的开头,它现在可以识别 GPU。但是,当我尝试
!nvidia-smi
时,终端输出仍然显示 Cuda 12.2。所以有些电线是交叉的,但 GPU 以某种方式变得可见..
不兼容2:发泄:keras_nlp的维护性和向后兼容性确实很差。如果不是 tf-lite,我不会去 keras 附近的任何地方。我找到了这个链接,其中提到:
您应该看到#998 中的示例。 Generator.generate 方法是 不是 JITable (您不能对其应用 tf.function 装饰器)。那么你 将不得不使用generate_function来代替它接受 由分词器生成的 token_ids 和 padding_mask 字典。 然后,您需要在 TF 图之外运行分词器。 像这样的东西:虽然我不完全理解这一点,但我尝试了很多keras_nlp和tensorflow版本组合,除了
keras_nlp==0.5.0
和
tensorflow==12.1
之外,没有任何效果。我了解 @tf.concrete 装饰器不喜欢任何 numpy 内容,并且他们在 Task 和 CausalLM 类的背景中进行了更改,从而使用新版本将所有内容转换为 .numpy() 左右。