python 3.10 이상 설치해야하는 것 같다. python3.10 부터는 openssl 1.1.1 이상이 필요하다.
yum install epel-release -y
yum install openssl11 openssl11-devel -y
yum -y install yum-utils
yum -y install mariadb-devel
yum -y install zlib zlib-devel libffi-devel bzip2-devel
yum -y install gcc gcc-c++ openssl openssl-devel
yum -y install zip unzip wget mc git net-tools
cd /opt
wget <https://www.python.org/ftp/python/3.11.3/Python-3.11.3.tgz> --no-check-certificate
tar -zxvf Python-3.11.3.tgz
cd Python-3.11.3
./configure
make
make install
pip install llama-index
텍스트 파일, PDF 파일, 웹 사이트, 데이터베이스, API 등의 데이터를 파이프라인에 넣는 것이다. LlamaHub에 다양한 connector가 있다.
데이터를 쿼리할 수 있는 자료 구조를 생성하는 것이다. LLM에서는 주로 벡터 임베딩을 의미한다.
데이터가 인덱싱되면 다시 인덱싱하지 않아도 되도록 그 인덱스를 저장한다.
LLM과 라마인덱스를 사용해서 쿼리할 수 있는 방법은 다양하다.
다른 방법에 비해 얼마나 효과적인지 확인하는 것도 중요하다. 쿼리에 대한 응답이 얼마나 믿을만하고 빠른지를 확인해준다.
문서가 한 번에 embedding 할 수 있는 크기보다 크다면 나눠서 embedding을 해야한다.
class ApiTool:
_api_cnt = 0
_segmentation_api_cnt = 0
_completion_api_cnt = 0
_embedding_api_cnt = 0
def __init__(self, access_token=None):
self._base_url = conf.llm_base_url
self._client_id = os.getenv("CLIENT_ID")
self._client_secret = os.getenv("CLIENT_SECRET")
if not self._client_id or not self._client_secret:
logger.error(f"Credential is required.")
sys.exit(1)
self._chat_model_name = conf.llm_model
self._embed_model_name = conf.embedding_model
if access_token is None:
self._refresh_access_token()
else:
self._access_token = access_token
self.docstore = SimpleDocumentStore()
def _refresh_access_token(self):
# If existingToken is true, it returns a token that has the longest expiry time among existing tokens.
u = f'{self._base_url}/v1/auth/token?existingToken=true'
...
r = requests.get(url=u, headers=headers)
self._api_cnt += 1
logger.info(f"Access Token refreshed: {self._access_token}")
def _request_post(self, url, json_body, headers, is_retry=False):
r = requests.post(url=url, json=json_body, headers=headers)
self._api_cnt += 1
try:
if r.statuc_code == 401:
# refresh token and retry
if r.status_code != 200:
self._refresh_access_token()
headers['Authorization'] = f'Bearer {self._access_token}'
raise Exception(f"{r.status_code} {r.text}")
except Exception as e:
logger.error(f"API failed.")
return r
def get_completion(self, query):
u = f'{self._base_url}/v1/completion/{self._chat_model_name}'
headers = {'Authorization': f'Bearer {self._access_token}'}
d = {...} # input query and parameters
r = self._request_post(url=u, json_body=d, headers=headers)
return r.json()['result']['message']['content']
class MyLLM(CustomLLM):
context_window: int = 2048
num_output: int = 256
model_name: str = "my-model"
chunk_size: int = 1024
dummy_response: str = "My Dummy Response"
error_response: str = "Something went wrong! Please contact administrator."
api_tool: ApiTool = None
def __init__(self, input_system_prompt: str = '', api_tool: ApiTool = None, **kwargs: Any) -> None:
super().__init__(**kwargs)
if input_system_prompt:
self.system_prompt = input_system_prompt
else:
self.system_prompt = system_prompt # llama_index/core/llms/llm 에서 _extend_prompt 해준다.
if api_tool:
self.api_tool = api_tool
else:
self.api_tool = ApiTool()
@property
def metadata(self) -> LLMMetadata:
return LLMMetadata(
context_window=self.context_window,
num_output=self.num_output,
model_name=self.model_name
)
@llm_completion_callback()
def complete(self, prompt: str, **kwargs: Any) -> CompletionResponse:
logger.debug(f"{prompt=}\n\n")
try:
completion = self.api_tool.get_completion(prompt)
except Exception as e:
logger.error(e)
return CompletionResponse(text=self.error_response)
return CompletionResponse(text=completion)
@llm_completion_callback()
def stream_complete(self, prompt: str, **kwargs: Any) -> CompletionResponseGen:
# todo: Not implemented yet
response = ""
for token in self.dummy_response:
response += token
yield CompletionResponse(text=response, delta=token)
# raise NotImplementedError()
References