BERT与TensorFlow
记录一下Bert与Tensorflow踩的坑。
1. RTX 3070与Tensorflow
最近换了一个RTX 3070显卡,想着能够愉快的GPU学习。
结果发现安装CUDA 11.0以下的版本,根本不会调用GPU(相关链接)。
而tensorflow-gpu与cuda和cudnn的版本对应显示,cuda11.0是和tensorflow-gpu 2.4对应的。
然而懒人配置环境常用的conda里,只有2.5和2.6版本。
所以,
RTX 3070 \(\Rightarrow\) tensorflow-gpu ≥ 2.5
2. Tensorflow与Bert
BERT作为NLP不得不用的一个模型,主流的是在tensorflow上写的。有一个好用库bert-for-tf2
,可以让BERT像keras的layer一样的模式调用,与TF2的编码形式一致(bert-for-tf2)。
然而在tensorflow-gpu 2.6环境下,调用它的会出现报错:
TypeError: Layer input_spec must be an instance of InputSpec. Got: InputSpec(shape=(None, 128, 768), ndim=3)
有的解决方法说是将tf版本降到2.0(链接),不过经实测,同样的程序在tensorflow-gpu 2.5环境下不会报错。
所以,
bert-for-tf2 \(\Rightarrow\) tensorflow-gpu ≤ 2.5
3. Tensorflow与Numpy
在tf-gpu 2.5版本下顺利运行Bert后,希望再在后面接上一个双向LSTM,然而却发现conda自动搭配的tf-gpu 2.5与numpy有一些冲突。在调用tf.keras.layers.Bidirectional
进行双向LSTM建模时,会报错:
NotImplementedError: Cannot convert a symbolic Tensor (bidirectional/forward_lstm/strided_slice:0) to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported
用的还是官网自带的例程:
点击查看代码
model = Sequential()
model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5, 10)))
model.add(Bidirectional(LSTM(10)))
model.add(Dense(5))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
网上部分将原因归为numpy版本高了(链接),尝试单独降numpy版本后,发现会报更多的错;并且并不一定是版本高的原因,这个问题在tf-gpu 2.6就不会出现,也许是库间的搭配做的不好。
Bidirectional \(\Rightarrow\) tensorflow-gpu \(\ne\) 2.5
结论
综上所述,立即推,怎么样?放弃TensorFlow,转Pytorch。