벡터 DB Weaviate 로컬에 설치하기

송윤주·2024년 6월 21일
0

데이터베이스

목록 보기
6/13

서론

필자는 지금 부트캠프를 다니고 있고... 이미 2차 프로젝트 때 weaviate를 사용했었다. weaviate를 선택한 이유는 아래와 같다.

  1. 벡터 데이터베이스이기 때문!
    • 벡터 db는 데이터의 의미적 유사성을 기반으로 검색을 수행한다. 그래서 nlp 애플리케이션에서 유사한 의미를 가진 문장을 찾을 때 유용하다.
  2. 논문을 구어체로 검색하는 용도에 적합함
    • elasticsearch, milvus, faiss, pinecone 등이 존재하지만 elasticsearch의 경우 이미 한번 써보기도 해서 다른 db를 경험하고 싶었다. 그리고 주로 텍스트 임베딩 같은 벡터 데이터 검색, 즉 벡터 유사도 검색에 강점이 있는 것은 weaviate라고 해서 이런 db를 선택하게 되었다.

필자는 지금 논문 관련 프로젝트를 진행중이기 때문에 해당 db가 필요했다. 그리고 논문 외에도 다른 텍스트 임베딩이 필요하다...!!! 어쨌든 필요함 ㅋㅋ





클라우드로 사용하기

사실은 이미 클라우드로 사용해보았다! 클라우드로 연결하는 것은 어렵지 않다.
https://weaviate.io/
단계별로 시작해보자~

회원가입

공식홈페이지로 가서 회원가입 후 로그인을 진행한다.

대시보드 확인

이렇게해서 로그인을 하면 대시보드가 아래처럼 나온다.

여기서 create cluster를 누르면 아래처럼 나오는데 클라우드는 14일만 무료이다. 추가로 사용하려면 managed cluster 로 생성해서 비용을 지불해야한다.

생성이 완료되었으면 파이썬 코드로는 아래처럼 짜서 연결할 수 있다.

연결해보기

그전에 pip install weaviate-client를 통해 설치하는 것은 필수!! 더불어 아래 코드는 v4 라서 가장 최신이다. 이전 버전 코드 즉 chatgpt한테 물어보면 나오는 코드는 v3버전이라 depreciated 라서 warning이 뜨기도 하고 어떤 기능은 작동되지 않는다... 이것때문에 엄청 애를 먹었다. chatgpt 붐다운 ;;;; 그래서 공식문서를 한올한올 핥아먹었다...

import weaviate
import os
  
# Set these environment variables
URL = os.getenv("WCS_URL")
APIKEY = os.getenv("WCS_API_KEY")
  
# Connect to a WCS instance
client = weaviate.connect_to_wcs(
    cluster_url=URL,
    auth_credentials=weaviate.auth.AuthApiKey(APIKEY))

이때 있는 WCS_URLWCS_API_KEY


샌드박스 토글을 열면 나오는 url과 api key를 발급받으면 된다!

# 연결 확인
if client.is_ready():
    print("Weaviate Cloud에 성공적으로 연결되었습니다.")
else:
    print("Weaviate Cloud에 연결할 수 없습니다.")

그런다음에 이 코드로 연결 상태를 확인해보면 연결 완료!





Docker compose로 연결하기

근데 나는... 비용은 지불하고 싶지 않고... 2주 뒤에도 계속 사용하고 싶고... 더불어 로컬에 깔고 싶은 것이다.. 싶으면!! 도커 컴포즈를 사용해서 설치할 수 있다. 이것도 공식문서를 참고했다.

docker-compose yml 파일

version: '3.4'

services:
  weaviate:
    image: semitechnologies/weaviate:latest
    ports:
      - 8080:8080
      - 50051:50051
    environment:
      - QUERY_DEFAULTS_LIMIT=20
      - AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true
      - PERSISTENCE_DATA_PATH=/var/lib/weaviate
      - ENABLE_MODULES=text2vec-huggingface
      - DEFAULT_VECTORIZER_MODULE=text2vec-huggingface
      - HUGGINGFACE_INFERENCE_APIKEY=${HUGGINGFACE_API_KEY}
      - WEAVIATE_ENABLE_GRPC=true
    volumes:
      - ./data:/var/lib/weaviate
    networks:
      - weaviate-network

networks:
  weaviate-network:
    driver: bridge

필자의 경우 이렇게 yml파일을 작성하였다. 텍스트 벡터화를 위해서 필자는 허깅페이스를 사용하기 때문에 저렇게 기입하였고 허깅페이스 외에도 공식문서를 참고해보면 다양한 벡터화 가능 모듈이 존재한다. 허깅페이스를 선택한 이유는... 비용도 안들고 gpu를 굳이 사용할 필요가 없고 좀 더 파인튜닝된 모델을 사용할 수 있기 때문이다. gpu를 사용해도 된다면 text2vec-transformers 를 사용하고 싶다.. ㅜㅠ 테스트 목적의 경량 모델을 원한다면 text2vec-contextionary 을 쓴다고 한다.

그리고 지금은 실사용자가 없는 공부 용도의 프로젝트이기 때문에 도커를 사용했으나 아래 표처럼 프로젝트 규모에 따라 쿠버네티스를 사용할 수 있다.

그리고 나는 source ~/.bashrc를 통해서 허깅페이스 api키를 환경변수화해서 yml파일에 저렇게 작성한 것이다! 다른 방법으로 키를 보호하는 방법이 있으나 일단 간단한 방법으로 작성!
그리고 나는 컨테이너를 삭제해도 실행했던 모든 파일이 남겨졌으면 해서
./data:/var/lib/weaviate 이렇게 영구 볼륨을 설정하였다.

연결 코드

import weaviate
import os
import weaviate.classes.config as wc


HUGGINGFACE_API_KEY = os.environ["HUGGINGFACE_API_KEY"]

client = weaviate.connect_to_local(
    headers={
        "X-HuggingFace-Api-Key": HUGGINGFACE_API_KEY,
    }
)

# 연결 확인
if client.is_ready():
    print("Weaviate Cloud에 성공적으로 연결되었습니다.")
else:
    print("Weaviate Cloud에 연결할 수 없습니다.")

로컬의 경우 이렇게 연결할 수 있다. 헤더는 내가 허깅페이스 벡터모델을 사용하니 넣어주었다. 만일 openai 도 사용한다면 그 키도 넣어주어야겠죵?!





에러파티

근데?!? 당연히 잘 안된다.. 내가 겪은 에러에 대해서 작성해보겠다.

docker-compose version문제

raceback (most recent call last):
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 214, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
                        ^^^^^^^^^^
.....
.....

File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 41, in get_client
    client = docker_client(
             ^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 170, in docker_client
    client = APIClient(use_ssh_client=not use_paramiko_ssh, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 197, in __init__
    self._version = self._retrieve_server_version()
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 221, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: HTTPConnection.request() got an unexpected keyword argument 'chunked'

이런 에러를 맞닥뜨렸는데 이건 버전 문제였다. 내 버전이 너무 낮아서 이것도 depreciated 된 것이였다.

해결 방법

which docker-compose

일단 이렇게 cmd창에 쳐서 원래 도커 컴포즈가 깔린 위치를 확인한다. 필자의 경우 /usr/bin/docker-compose 이곳이였고 해당 파일을 삭제했다.

그다음 최신 버전을 알기 위해서 github 에서 확인하였고

sudo curl -L "https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose
sudo chmod +x /usr/bin/docker-compose
docker-compose --version

이명령어를 통해서 설치하고 버전을 확인한 결과 최신버전이 깔렸고 해당 에러를 잡았다.

포트 문제

yml 파일에 처음에는 - "8080:8080" 이렇게 한개만 작성했는데 그러다 보니 연결이 되지 않았고 docker-compose logs weaviate 를 통해 로그를 확인해보았다.

...
["172.19.0.2:8300"],"time":"2024-06-20T07:51:09Z"}
weaviate-1  | {"action":"startup","error":"bootstrap: context deadline exceeded","level":"fatal","msg":"could not open cloud meta store","time":"2024-06-20T07:51:09Z"}

이렇게 Weaviate가 클러스터에 참여할 수 없다는 로그를 확인할 수 있었다.

그리고 아래처럼

Traceback (most recent call last):
  File "/work/aws_ai_pj/.venv/lib/python3.9/site-packages/weaviate/connect/v4.py", line 696, in _ping_grpc
    res: health_pb2.HealthCheckResponse = self._grpc_channel.unary_unary(
  File "/work/aws_ai_pj/.venv/lib/python3.9/site-packages/grpc/_channel.py", line 1181, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/work/aws_ai_pj/.venv/lib/python3.9/site-packages/grpc/_channel.py", line 1006, in _end_unary_response_blocking
    raise _InactiveRpcError(state)  # pytype: disable=not-instantiable
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
        status = StatusCode.UNAVAILABLE
        details = "failed to connect to all addresses; last error: UNKNOWN: ipv4:127.0.0.1:50051: Failed to connect to remote host: Connection refused"
        debug_error_string = "UNKNOWN:Error received from peer  {grpc_message:"failed to connect to all addresses; last error: UNKNOWN: ipv4:127.0.0.1:50051: Failed to connect to remote host: Connection refused", grpc_status:14, created_time:"2024-06-20T08:00:19.182771433+00:00"}"

gRPC 설정 또는 서버 접근 문제가 있다는 로그를 확인할 수 있었다.

해결 방법

yml 파일을 처음에 작성한대로 gRPC 를 위한 50051 포트를 추가하고 WEAVIATE_ENABLE_GRPC=true 부분도 추가하고 네트워크 부분도 추가했다.
포트를 두개 노출 시키는 것은 Weaviate가 HTTP(8080)와 gRPC(50051) 트래픽을 처리할 수 있게 하는 것이다.

더불어 기존 데이터로 인해 문제가 발생할 수 있으니 rm -rf ./data 로 기존 데이터를 지우고 다시 도커 컴포즈를 올렸더니 성공~~~!!





결론

공식문서의 모든 것을 핥아먹다 보니 공식문서를 학습해서 코드를 알려주는 ai가 있었으면 좋겠다는 생각이 마구마구 들었다... 공식문서의 url만 넣으면 바로 알려주는 것이지...
그리고 영어를 잘하고 싶다... 왜 공용어가 영어인 것인가~~~

profile
모두가 정보를 습득할 수 있도록 냠냠쩝쩝 먹어보는 공간

0개의 댓글