171 lines
4.6 KiB
Python
171 lines
4.6 KiB
Python
"""
|
|
Utility Tools for the Portkey Class.
|
|
|
|
This file module contains a collection of utility functions designed to enhance
|
|
the functionality and usability of the Portkey class
|
|
"""
|
|
from typing import TYPE_CHECKING, List
|
|
|
|
from llama_index.core.llms.types import LLMMetadata
|
|
from llama_index.llms.anthropic import Anthropic
|
|
from llama_index.llms.anthropic_utils import CLAUDE_MODELS
|
|
from llama_index.llms.openai import OpenAI
|
|
from llama_index.llms.openai_utils import (
|
|
AZURE_TURBO_MODELS,
|
|
GPT3_5_MODELS,
|
|
GPT3_MODELS,
|
|
GPT4_MODELS,
|
|
TURBO_MODELS,
|
|
)
|
|
|
|
if TYPE_CHECKING:
|
|
from portkey import (
|
|
LLMOptions,
|
|
PortkeyResponse,
|
|
)
|
|
|
|
|
|
IMPORT_ERROR_MESSAGE = (
|
|
"Portkey is not installed.Please install it with `pip install portkey-ai`."
|
|
)
|
|
|
|
|
|
DISCONTINUED_MODELS = {
|
|
"code-davinci-002": 8001,
|
|
"code-davinci-001": 8001,
|
|
"code-cushman-002": 2048,
|
|
"code-cushman-001": 2048,
|
|
}
|
|
|
|
DEFAULT_MODEL = "gpt-3.5-turbo"
|
|
|
|
AVAILABLE_INTEGRATIONS = (OpenAI, Anthropic)
|
|
|
|
CLUADE_MODEL_FULLVERSION_MAP = {
|
|
"claude-instant-1": "claude-instant-1.2",
|
|
"claude-2": "claude-2.0",
|
|
}
|
|
|
|
ALL_AVAILABLE_MODELS = {
|
|
**GPT4_MODELS,
|
|
**TURBO_MODELS,
|
|
**GPT3_5_MODELS,
|
|
**GPT3_MODELS,
|
|
**AZURE_TURBO_MODELS,
|
|
**CLAUDE_MODELS,
|
|
}
|
|
|
|
CHAT_MODELS = {
|
|
**GPT4_MODELS,
|
|
**TURBO_MODELS,
|
|
**AZURE_TURBO_MODELS,
|
|
}
|
|
|
|
|
|
def is_chat_model(model: str) -> bool:
|
|
"""Check if a given model is a chat-based language model.
|
|
|
|
This function takes a model name or identifier as input and determines whether
|
|
the model is designed for chat-based language generation, conversation, or
|
|
interaction.
|
|
|
|
Args:
|
|
model (str): The name or identifier of the model to be checked.
|
|
|
|
Returns:
|
|
bool: True if the provided model is a chat-based language model,
|
|
False otherwise.
|
|
"""
|
|
return model in CHAT_MODELS
|
|
|
|
|
|
def modelname_to_contextsize(modelname: str) -> int:
|
|
"""Calculate the maximum number of tokens possible to generate for a model.
|
|
|
|
Args:
|
|
modelname: The modelname we want to know the context size for.
|
|
|
|
Returns:
|
|
The maximum context size
|
|
|
|
Example:
|
|
.. code-block:: python
|
|
|
|
max_tokens = modelname_to_contextsize("text-davinci-003")
|
|
"""
|
|
# handling finetuned models
|
|
if "ft-" in modelname: # legacy fine-tuning
|
|
modelname = modelname.split(":")[0]
|
|
elif modelname.startswith("ft:"):
|
|
modelname = modelname.split(":")[1]
|
|
|
|
if modelname in DISCONTINUED_MODELS:
|
|
raise ValueError(
|
|
f"Model {modelname} has been discontinued. " "Please choose another model."
|
|
)
|
|
|
|
context_size = ALL_AVAILABLE_MODELS.get(modelname, None)
|
|
|
|
if context_size is None:
|
|
raise ValueError(
|
|
f"Unknown model: {modelname}. Please provide a valid model name."
|
|
"Known models are: " + ", ".join(ALL_AVAILABLE_MODELS.keys())
|
|
)
|
|
|
|
return context_size
|
|
|
|
|
|
def generate_llm_metadata(llm: "LLMOptions") -> LLMMetadata:
|
|
"""
|
|
Generate metadata for a Language Model (LLM) instance.
|
|
|
|
This function takes an instance of a Language Model (LLM) and generates
|
|
metadata based on the provided instance. The metadata includes information
|
|
such as the context window, number of output tokens, chat model status,
|
|
and model name.
|
|
|
|
Parameters:
|
|
llm (LLM): An instance of a Language Model (LLM) from which metadata
|
|
will be generated.
|
|
|
|
Returns:
|
|
LLMMetadata: A data structure containing metadata attributes such as
|
|
context window, number of output tokens, chat model status, and
|
|
model name.
|
|
|
|
Raises:
|
|
ValueError: If the provided 'llm' is not an instance of
|
|
llama_index.llms.base.LLM.
|
|
"""
|
|
try:
|
|
from portkey import LLMOptions
|
|
except ImportError as exc:
|
|
raise ImportError(IMPORT_ERROR_MESSAGE) from exc
|
|
if not isinstance(llm, LLMOptions):
|
|
raise ValueError("llm must be an instance of portkey.LLMOptions")
|
|
|
|
return LLMMetadata(
|
|
_context_window=modelname_to_contextsize(llm.model or ""),
|
|
is_chat_model=is_chat_model(llm.model or ""),
|
|
model_name=llm.model,
|
|
)
|
|
|
|
|
|
def get_llm(response: "PortkeyResponse", llms: List["LLMOptions"]) -> "LLMOptions":
|
|
# TODO: Update this logic over here.
|
|
try:
|
|
from portkey import LLMOptions
|
|
except ImportError as exc:
|
|
raise ImportError(IMPORT_ERROR_MESSAGE) from exc
|
|
fallback_llm = LLMOptions.construct()
|
|
for llm in llms:
|
|
model = llm.model
|
|
|
|
if model == response.model:
|
|
fallback_llm = llm
|
|
break
|
|
|
|
if fallback_llm is None:
|
|
raise ValueError("Failed to get the fallback LLM")
|
|
return fallback_llm
|