从 s3 加载 fasttext 二进制模型失败
Loading fasttext binary model from s3 fails
我在 s3 上托管了一个预训练的 fasttext 模型(未压缩),我正在尝试将其加载到 lambda 函数中。我正在使用 gensim.models.fasttext
模块加载模型:
from gensim.models.fasttext import load_facebook_vectors
def load_model(obj):
model = load_facebook_vectors(obj["path"])
obj["path"]
是 s3 路径,但我不断收到以下错误:
"errorMessage": "fileno"
"errorType": "UnsupportedOperation"
"stackTrace": [
...
" File \"/var/task/gensim/models/fasttext.py\", line 784, in load_facebook_vectors\n full_model = _load_fasttext_format(path, encoding=encoding, full_model=False)\n"
" File \"/var/task/gensim/models/fasttext.py\", line 808, in _load_fasttext_format\n m = gensim.models._fasttext_bin.load(fin, encoding=encoding, full_model=full_model)\n"
" File \"/var/task/gensim/models/_fasttext_bin.py\", line 348, in load\n vectors_ngrams = _load_matrix(fin, new_format=new_format)\n"
" File \"/var/task/gensim/models/_fasttext_bin.py\", line 282, in _load_matrix\n matrix = np.fromfile(fin, _FLOAT_DTYPE, count)\n"
]
不幸的是,此加载所依赖的 np.fromfile()
方法不适用于 streamed-from-S3 文件。
一些替代选项包括:
- 首先将 S3 文件下载到本地路径,然后从那里使用
load_facebook_vectors()
;或者……
- 在本地拥有 FastText 文件的同时,在本地加载它,然后使用 Python 的
pickle
功能将其保存到单个文件(现在是 Python 的格式) ,然后将该文件放在 S3 上,并在将来 re-load 使用 Python 的 unpickling
gensim.utils
pickle()
和 unpickle()
中的实用函数(采用文件路径,包括 S3 URL)可能对第二个选项有帮助,例如:
https://radimrehurek.com/gensim/utils.html#gensim.utils.unpickle
由于您之前的代码仅显示使用矢量(通过 .load_facebook_vector
),而不是整个模型,您可以只腌制并上传加载模型的 model.wv
子组件,而不是整个模型,保存一些storage/bandwidth.
如果可能在未来的 Gensim 版本中,FastText
模型相关 类 在 shape/operation 中发生变化,旧的 pickled-model 可能无法干净地加载。在这种情况下,您可能会:
- 返回原始 Facebook-format 模型文件(然后可以加载,然后再次以现代格式 re-saved);或者...
- 将你的 pickled 模型加载到它工作的旧 Gensim 中,使用 Gensim 的原生
.save()
将其保存在本地(这可能会将其拆分为多个本地文件),然后在较新的 Gensim 中使用 Gensim 的原生 FastText.load()
加载那些旧文件(通常会处理旧格式),然后 re-pickle 加载模型,以便将来 re-unpickles 到匹配的最新 Gensim 中。
load_facebook_vectors 的文档说:
This function uses the smart_open library to open the path. The path may be on a remote host (e.g. HTTP, S3, etc).
在 smart_open 有访问 S3 对象的示例。我没有亲自尝试过,但我想确保在决定强制下载对象并在本地访问它之前消除所有选项。
我在 s3 上托管了一个预训练的 fasttext 模型(未压缩),我正在尝试将其加载到 lambda 函数中。我正在使用 gensim.models.fasttext
模块加载模型:
from gensim.models.fasttext import load_facebook_vectors
def load_model(obj):
model = load_facebook_vectors(obj["path"])
obj["path"]
是 s3 路径,但我不断收到以下错误:
"errorMessage": "fileno"
"errorType": "UnsupportedOperation"
"stackTrace": [
...
" File \"/var/task/gensim/models/fasttext.py\", line 784, in load_facebook_vectors\n full_model = _load_fasttext_format(path, encoding=encoding, full_model=False)\n"
" File \"/var/task/gensim/models/fasttext.py\", line 808, in _load_fasttext_format\n m = gensim.models._fasttext_bin.load(fin, encoding=encoding, full_model=full_model)\n"
" File \"/var/task/gensim/models/_fasttext_bin.py\", line 348, in load\n vectors_ngrams = _load_matrix(fin, new_format=new_format)\n"
" File \"/var/task/gensim/models/_fasttext_bin.py\", line 282, in _load_matrix\n matrix = np.fromfile(fin, _FLOAT_DTYPE, count)\n"
]
不幸的是,此加载所依赖的 np.fromfile()
方法不适用于 streamed-from-S3 文件。
一些替代选项包括:
- 首先将 S3 文件下载到本地路径,然后从那里使用
load_facebook_vectors()
;或者…… - 在本地拥有 FastText 文件的同时,在本地加载它,然后使用 Python 的
pickle
功能将其保存到单个文件(现在是 Python 的格式) ,然后将该文件放在 S3 上,并在将来 re-load 使用 Python 的 unpickling
gensim.utils
pickle()
和 unpickle()
中的实用函数(采用文件路径,包括 S3 URL)可能对第二个选项有帮助,例如:
https://radimrehurek.com/gensim/utils.html#gensim.utils.unpickle
由于您之前的代码仅显示使用矢量(通过 .load_facebook_vector
),而不是整个模型,您可以只腌制并上传加载模型的 model.wv
子组件,而不是整个模型,保存一些storage/bandwidth.
如果可能在未来的 Gensim 版本中,FastText
模型相关 类 在 shape/operation 中发生变化,旧的 pickled-model 可能无法干净地加载。在这种情况下,您可能会:
- 返回原始 Facebook-format 模型文件(然后可以加载,然后再次以现代格式 re-saved);或者...
- 将你的 pickled 模型加载到它工作的旧 Gensim 中,使用 Gensim 的原生
.save()
将其保存在本地(这可能会将其拆分为多个本地文件),然后在较新的 Gensim 中使用 Gensim 的原生FastText.load()
加载那些旧文件(通常会处理旧格式),然后 re-pickle 加载模型,以便将来 re-unpickles 到匹配的最新 Gensim 中。
load_facebook_vectors 的文档说:
This function uses the smart_open library to open the path. The path may be on a remote host (e.g. HTTP, S3, etc).
在 smart_open 有访问 S3 对象的示例。我没有亲自尝试过,但我想确保在决定强制下载对象并在本地访问它之前消除所有选项。