es自2020年的8.x版本以來,就提供了機器學習的能力。我們可以使用es官方提供的工具eland,將hugging face上的NLP模型,上傳到es集群中。利用es的機器學習模塊,來運維部署管理模型。配合es的管道處理,來更加便捷的處理數據。但是在國內操作,根據官方文檔或者根據官方博客操作,有無窮無盡的坑。看著官方的文檔寫的很清楚,實際上操作的時候,還是操作不下來。這里寫一個閉坑指南。在你上車體驗ES的機器學習之前,看看我這篇文章,肯定是會有收獲的。因為我已經花了時間,踩了坑,并解決了它。
上傳模型存在的坑
- 第一個坑是,es的機器學習,是收費的功能,白金版才能使用。這里需要開啟試用才能用(試用期限為一個月)。如果只是體驗,一個月已經足夠了。體驗效果不錯,就可以找老板花錢了。(不過網上也有很多綠色的方案,可以用,不推薦,有法律風險,特別是商用)
- 開啟白金試用,需要開啟xpack安全認證,開啟用戶認證,在kibana上登錄的時候,要使用elastic用戶登錄,否則無法開啟試用,會告訴你無權限。
- 網絡環境問題。如果你能開啟科學上網,肯定可以避免問題。但是即使有科學上網,也只是體驗一下。并不是生產實踐方案,生產環境通常都是在內網環境下,即使能上網,也肯定是在國內網絡環境下。這會有各種各樣的問題。所以要做我們就做生產環境版本,要做就做離線版本。舉一個最簡答的例子,國內的網絡,很難訪問huggingface,去拉取模型。
這里是我直接使用eland,上傳模型的時候遇到的錯誤。
docker?run?-it???-v?/u01/isi/.cache/huggingface/hub/:/usr/local/bin/eland_import_hub_model??--rm?elastic/eland?\ eland_import_hub_model?\ --url?http://elastic:123123@10.99.100.49:9200?\ --hub-model-id?sentence-transformers/clip-ViT-B-32-multilingual-v1?\ --task-type?text_embedding?\ --start
報錯為無法訪問huggingface.co?國內域名污染導致的。如果可以掛代理,可以解決。如果沒有代理,則看下邊離線安裝版本
2023-11-22 09:40:30,738?INFO?:?Establishing?connection?to?Elasticsearch 2023-11-22 09:40:30,751?INFO?:?Connected?to?cluster?named?'es'?(version: 8.8.0) 2023-11-22 09:40:30,752?INFO?:?Loading?HuggingFace?transformer?tokenizer?and?model?'sentence-transformers/clip-ViT-B-32-multilingual-v1' 'HTTPSConnectionPool(host='huggingface.co', port=443):?Max?retries?exceeded?with?url: /sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/tokenizer_config.json?(Caused?by?ConnectTimeoutError(<urllib3.connection.HTTPSConnection?object?at?0x7f50eb16cc10>,?'Connection?to?huggingface.co?timed?out. (connect?timeout=10)'))'?thrown?while?requesting?HEAD?https://huggingface.co/sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/tokenizer_config.json 2023-11-22 09:40:41,125?WARNING?:?'HTTPSConnectionPool(host='huggingface.co', port=443):?Max?retries?exceeded?with?url: /sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/tokenizer_config.json?(Caused?by?ConnectTimeoutError(<urllib3.connection.HTTPSConnection?object?at?0x7f50eb16cc10>,?'Connection?to?huggingface.co?timed?out. (connect?timeout=10)'))'?thrown?while?requesting?HEAD?https://huggingface.co/sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/tokenizer_config.json 'HTTPSConnectionPool(host='huggingface.co', port=443):?Max?retries?exceeded?with?url: /sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/config.json?(Caused?by?ConnectTimeoutError(<urllib3.connection.HTTPSConnection?object?at?0x7f50eb16cfd0>,?'Connection?to?huggingface.co?timed?out. (connect?timeout=10)'))'?thrown?while?requesting?HEAD?https://huggingface.co/sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/config.json 2023-11-22 09:40:51,583?WARNING?:?'HTTPSConnectionPool(host='huggingface.co', port=443):?Max?retries?exceeded?with?url: /sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/config.json?(Caused?by?ConnectTimeoutError(<urllib3.connection.HTTPSConnection?object?at?0x7f50eb16cfd0>,?'Connection?to?huggingface.co?timed?out. (connect?timeout=10)'))'?thrown?while?requesting?HEAD?https://huggingface.co/sentence-transformers/clip-ViT-B-32-multilingual-v1/resolve/main/config.json Traceback?(most?recent?call?last):File "/usr/local/lib/python3.9/dist-packages/transformers/utils/hub.py",?line?409, in?cached_file ????resolved_file?= hf_hub_download(File "/usr/local/lib/python3.9/dist-packages/huggingface_hub/utils/_validators.py",?line?118, in?_inner_fnreturn fn(*args, **kwargs)File "/usr/local/lib/python3.9/dist-packages/huggingface_hub/file_download.py",?line?1291, in?hf_hub_download ????raise?LocalEntryNotFoundError( huggingface_hub.utils._errors.LocalEntryNotFoundError:?Connection?error, and?we?cannot?find?the?requested?files?in?the?disk?cache.?Please?try?again?or?make?sure?your?Internet?connection?is on.During?handling?of?the?above?exception,?another?exception?occurred:Traceback?(most?recent?call?last):File "/usr/local/bin/eland_import_hub_model",?line?219, in <module> ????tm?= TransformerModel(model_id=args.hub_model_id,?task_type=args.task_type,?es_version=cluster_version,?quantize=args.quantize)File "/usr/local/lib/python3.9/dist-packages/eland/ml/pytorch/transformers.py",?line?613, in?__init__ ????self._tokenizer?=?transformers.AutoTokenizer.from_pretrained(File "/usr/local/lib/python3.9/dist-packages/transformers/models/auto/tokenization_auto.py",?line?634, in?from_pretrained ????config?=?AutoConfig.from_pretrained(File "/usr/local/lib/python3.9/dist-packages/transformers/models/auto/configuration_auto.py",?line?896, in?from_pretrained ????config_dict,?unused_kwargs?=?PretrainedConfig.get_config_dict(pretrained_model_name_or_path, **kwargs)File "/usr/local/lib/python3.9/dist-packages/transformers/configuration_utils.py",?line?573, in?get_config_dict ????config_dict,?kwargs?=?cls._get_config_dict(pretrained_model_name_or_path, **kwargs)File "/usr/local/lib/python3.9/dist-packages/transformers/configuration_utils.py",?line?628, in?_get_config_dict ????resolved_config_file?= cached_file(File "/usr/local/lib/python3.9/dist-packages/transformers/utils/hub.py",?line?443, in?cached_file ????raise?EnvironmentError( OSError:?We?couldn't?connect?to?'https://huggingface.co'?to?load?this?file,?couldn't?find?it?in?the?cached?files?and?it?looks?like?sentence-transformers/clip-ViT-B-32-multilingual-v1?is not?the?path?to?a?directory?containing?a?file?named?config.json. Checkout?your?internet?connection?or?see?how?to?run?the?library in?offline?mode?at?'https://huggingface.co/docs/transformers/installation#offline-mode'.
- 官方指定的向es中導入NLP模型的工具是Eland,下載和構建鏡像也是有網絡問題,這里需要指定國內的鏡像源。
- 關于從hugging face上拉取NLP模型的問題。使用eland,它可以根據我們指定的模型id,去hugging face上拉取模型,但是還是國內的網絡環境問題,死活拉不下來。因為無法訪問huggingface域名。
- 目前,截止到2023年12月2號為止。es所謂的機器學習能力,僅支持文本類操作的模型。官方一直在說擁有跨模態的能力。實際上es并不支持,將圖片轉向量的模型導入到es中(例如常用的CLIP多模態模型,其實它是兩部分,雙塔模型,一個是將圖片做embedding,轉成向量。另一個模型是將我們的文本內容做embedding轉為向量。其中圖片轉向量的模型,在es中是不支持上傳的,文本轉向量的模型是可以上傳的)。如下所示,上傳clip 將圖片轉為向量的模型。會報錯
docker run -it -v /u01/isi/.cache/huggingface/hub/sentence-transformers/clip-vit-base-patch32:/eland/sentence-transformers/clip-vit-base-patch32 --rm elastic/eland \
eland_import_hub_model \
--url http://elastic:123123@10.99.100.49:9200 \
--hub-model-id sentence-transformers/clip-vit-base-patch32 \
--task-type text_embedding \
--start
報錯如下
準備工作
1. 需要搭建一個8.8以上版本的ES集群。默認會開啟安全訪問認證,不要關它。
2. 使用源碼構建eland工具
3. 從huggingface上,離線下載NLP模型
4. 將模型上傳到構建eland的服務器上
安裝Elasticsearch 和kibana
?這里參看以下文章,跟著搭建集群就可以了(其實我整個導入的過程,也是參考的這篇文章,只是在國內安裝,遇到了上述的坑)。
Elasticsearch:如何在?Elastic?中實現圖片相似度搜索_es?相似度查詢_Elastic?中國社區官方博客的博客-CSDN博客
?搭建的es版本>=8.8.0?,一定要開安全認證,不然無法開啟機器學習的試用,無法導入模型
需要kibana
開啟試用
可以看到模型
安裝準備Eland
eland是如何工作的
?Eland?可以從huggingFace上,把模型下載下來,并上傳導es中。如下圖所示
應該如何安裝eland
這里提供在線的方式,和離線的方式。
Eland?可以通過?pip?從?PyPI?安裝
在安裝之前,我們需要安裝好自己的?Python。
$?python?--version
Python?3.10.2
可以使用?Pip?從?PyPI?安裝?Eland:
python?-m?pip?install?eland
可以使用?Conda?從?Conda?Forge?安裝?Eland
conda?install?-c?conda-forge?eland
Docker容器的方式來使用它
希望在不安裝?Eland?的情況下使用它,為了只運行可用的腳本,可以構建?Docker?容器。個人認為這種方式是最符合生產環境的部署方式。易交付。可以移植,不依賴網絡環境,可以提前構件好,然后將eland鏡像導入。
?第一步需要需要在有網的環境下,下載源碼。可以將源碼上傳到有docker環境的服務器上。(如果沒有docker環境,可以以最簡單的方式來安裝docker,這里就不提供方法了,可以網上搜搜文章,是在不行麻煩麻煩運維同事)
# 下載源碼
git?clone?https://github.com/elastic/eland# 這里可以把源碼上傳到有docker環境的,且能夠訪問到es集群的服務器上。
cd?eland這里注意,因為是在國內,我們先pass掉掛代理的事情(并不一定每個人都能掛代理)
這里需要先編輯一下dockerFile,添加指定國內的源。添加如下一行
RUN python3 -m pip install --no-cache-dir --disable-pip-version-check .[all] -i https://mirror.baidu.com/pypi/simple
#然后構建鏡像
docker?build?-t?elastic/eland?.
在huggingface上下載所需的NLP模型
?在huggingface上找到該模型。(這里可以根據自己的需求,找到合適的模型)這里我以CLIP的模型為例(這個是clip中做文本embedding的模型),來下載。
https://huggingface.co/sentence-transformers/clip-ViT-B-32-multilingual-v1/tree/main
全部下載下來
然后上傳到有eland的服務器上
使用eland 將離線模型導入到es集群中
我是以docker的方式來運行eland的。?
這次主要是加里一個數據卷,我把下載后的模型,放在了?/u01/isi/.cache/huggingface/hub/sentence-transformers/clip-ViT-B-32-multilingual-v1?下,然后加了一個數據拒卷。把模型映射到了容器中。這里因為服務器無法訪問huggingface去拉取模型。所以用離線的方式。eland,會在運行過程中,檢查本地有沒有模型,如果有模型,就不用去huggingface上拉取了。
注意eland的掛載目錄,docker中映射的是/eland/目錄,這樣才能讀到本地下載好的模型!
docker?run?-it???-v?/u01/isi/.cache/huggingface/hub/:/eland/???--rm?elastic/eland?\
eland_import_hub_model?\
--url?http://elastic:123123@10.99.100.49:9200?\
--hub-model-id?sentence-transformers/clip-ViT-B-32-multilingual-v1?\
--task-type?text_embedding?\
--start
可以看到,這里已經成功的導入模型了。
然后在kiabna上,找到模型管理,刷新一下。
已經成功刷新了出來
測試使用模型
對內容進行文本嵌入,在kiban上執行以下內容。點擊D旁邊的菜單欄,找到 Dev tools
POST?_ml/trained_models/sentence-transformers__clip-vit-b-32-multilingual-v1/_infer
{"docs" : [{"text_field": "Yellow?mountain?is?the?most?beautiful?mountain?in?China"}]
}
可以看到成功,應用模型,將文本內容,轉成了向量。?