opensearchpyでtimeoutが使えない

opensearchpyのドキュメントにはtimeoutを引数で渡せると書いてあるけど、使えないのを忘れてハマるので、メモ的に残す。

このIssueにもあるように、

client.search(..., timeout=120)

みたいにすると、

opensearchpy.exceptions.ConnectionError: ConnectionError(Timeout value connect was 120, but it must be an int, float or None.) caused by: ValueError(Timeout value connect was 120, but it must be an int, float or None.)

みたいな感じで、Errorが発生する。timeoutを指定したい場合は

client.search(..., params={"timeout":120})

のような感じで、paramsで渡せば指定できる。

No module named ‘torch._six’

Dollyを試してみようと思い、

git clone https://github.com/databrickslabs/dolly.git
cd dolly
pip install -r requirements.txt

をして、Getting Started with Response Generationを実行してみたけど、

ModuleNotFoundError: No module named 'torch._six'

という感じで怒られる…。ぐぐってみると、._sixを消せば良いとのことなので、

sed -i "s/._six//" /usr/local/lib/python3.9/dist-packages/deepspeed/runtime/utils.py
sed -i "s/._six//" /usr/local/lib/python3.9/dist-packages/deepspeed/runtime/zero/stage_1_and_2.py

みたいな感じで、対象箇所を修正。でも、40Gのメモリーを積んだGPUでも、

from transformers import pipeline

from transformers import pipeline

instruct_pipeline = pipeline(model="databricks/dolly-v2-12b", trust_remote_code=True, device_map="auto")

の方はメモリー不足と言われる…。(厳しい時代だな…)

なので、

import torch
from transformers import pipeline

instruct_pipeline = pipeline(model="databricks/dolly-v2-12b", torch_dtype=torch.bfloat16, trust_remote_code=True, device_map="auto")

を実行したら、処理できた。でも、24Gのメモリーを使っているっぽい…。Colab ProのGPUプレミアム設定で確認した感じです。

Dolly自体については、ChatGPTと比べると、現時点では、これから頑張っていく感じなのかなみたいな感じかな。

No module named ‘faiss.swigfaiss_avx2’

pipでfaissをインストールして利用していると、

INFO:faiss.loader:Loading faiss with AVX2 support.
INFO:faiss.loader:Could not load library with AVX2 support due to:
ModuleNotFoundError("No module named 'faiss.swigfaiss_avx2'")

のようなログが出る。つまり、AVX2が利用できていない感じだと思うが、これの対応方法は、この情報によると、swigfaiss.pyをシンボリックリンクを作っておけば良いとのことで、試したらこのメッセージがなくなった。

cd your_python_path/site-packages/faiss
ln -s swigfaiss.py swigfaiss_avx2.py

Tensorboardが表示されない

Jupyterノートブックで

%load_ext tensorboard
%tensorboard --logdir="/tmp/ranking_model_dir" --port 12345

のように書いて実行したら、

Reusing TensorBoard on port 12345 (pid 808444), started 1:12:35 ago. (Use '!kill 808444' to kill it.)

という感じで、Tensorboardが表示されず、プロセスをkillしようにもそのようなプロセスがいないような場合、前の情報が残っているだけかもしれません。ということで、

$ rm -rf /tmp/.tensorboard-info/

という感じで消してあげると表示されるようになりました。

FastAPIで画像をアップロードしてダウンロードする

FastAPIを使って、画像をアップロードして、OpenCVで変換とかして、返却するというのをやりたかったのだが、イマイチな部分もある気はするけど、メモがてらに残しておく。一応、アップロードされたファイルは一旦、一時ファイルに保存している(保存しなくても良いかもしれないけど…)。そんで、process(img)の中で、画像のimgのnumpy arrayを何か変換して、戻した画像のimg_convertedのnumpy arrayを作る。あとは、img_convertedはオンメモリでcv2.imencodeで、png形式にして、Responseで返せば、画像がダウンロードされる。画像はマルチパートでアップロードする感じだけど、FastAPIのhttp://localhost:8000/docs/で送り方を確認すればよいはず。

from fastapi import FastAPI, UploadFile, File, HTTPException, Response
import cv2
import shutil
from pathlib import Path
from tempfile import NamedTemporaryFile

app = FastAPI()


@app.post("/convert/")
def convert(file: UploadFile = File(...)):
    filepath = save_upload_file_tmp(file)
    try:
        img = cv2.imread(str(filepath))
        img_converted = process(img) # OpenCVの変換処理とか
        _, img_enc = cv2.imencode('.png', img_converted)
        return Response(content=img_enc.tostring(), media_type='image/png')
    except Exception as e:
        raise HTTPException(status_code=500, detail='Failed to convert an image.')
    finally:
        filepath.unlink()


def save_upload_file_tmp(upload_file: UploadFile) -> Path:
    try:
        suffix = Path(upload_file.filename).suffix
        with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
            shutil.copyfileobj(upload_file.file, tmp)
        tmp_path = Path(tmp.name)
    finally:
        upload_file.file.close()
    return tmp_path

FastAPIでアップロードされたファイルの保存はこれを参考にした。