Alwrity - WIP - main_config
This commit is contained in:
46
lib/gpt_providers/text_generation/gemini_pro_text.py
Normal file
46
lib/gpt_providers/text_generation/gemini_pro_text.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# Using Gemini Pro LLM model
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import google.generativeai as genai
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv(Path('../../../.env'))
|
||||
from loguru import logger
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
from tenacity import (
|
||||
retry,
|
||||
stop_after_attempt,
|
||||
wait_random_exponential,
|
||||
) # for exponential backoff
|
||||
|
||||
|
||||
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
|
||||
def gemini_text_response(prompt, temperature, top_p, n, max_tokens):
|
||||
""" Common functiont to get response from gemini pro Text. """
|
||||
try:
|
||||
genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
|
||||
except Exception as err:
|
||||
logger.error(f"Failed to configure Gemini: {err}")
|
||||
logger.info(f"Temp: {temperature}, MaxTokens: {max_tokens}, TopP: {top_p}, N: {n}")
|
||||
# Set up the model
|
||||
generation_config = {
|
||||
"temperature": temperature,
|
||||
"top_p": top_p,
|
||||
"top_k": n,
|
||||
"max_output_tokens": max_tokens
|
||||
}
|
||||
model = genai.GenerativeModel(model_name="gemini-pro", generation_config=generation_config)
|
||||
try:
|
||||
response = model.generate_content(prompt, stream=True)
|
||||
for chunk in response:
|
||||
print(chunk.text)
|
||||
return response.text
|
||||
except Exception as err:
|
||||
logger.error(response)
|
||||
logger.error(f"Failed to get response from Gemini: {err}. Retrying.")
|
||||
151
lib/gpt_providers/text_generation/main_text_generation.py
Normal file
151
lib/gpt_providers/text_generation/main_text_generation.py
Normal file
@@ -0,0 +1,151 @@
|
||||
import os
|
||||
import sys
|
||||
import configparser
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv(Path('../.env'))
|
||||
|
||||
from loguru import logger
|
||||
logger.remove()
|
||||
logger.add(sys.stdout,
|
||||
colorize=True,
|
||||
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
|
||||
)
|
||||
|
||||
from .openai_text_gen import openai_chatgpt
|
||||
from .gemini_pro_text import gemini_text_response
|
||||
|
||||
|
||||
def llm_text_gen(prompt):
|
||||
"""
|
||||
Generate text using Language Model (LLM) based on the provided prompt.
|
||||
Args:
|
||||
prompt (str): The prompt to generate text from.
|
||||
Returns:
|
||||
str: Generated text based on the prompt.
|
||||
"""
|
||||
try:
|
||||
config_path = Path(__file__).resolve().parents[3] / "main_config"
|
||||
gpt_provider, model, temperature, max_tokens, top_p, n, fp = read_llm_parameters(config_path)
|
||||
|
||||
gpt_provider = check_gpt_provider(gpt_provider)
|
||||
# Check if API key is provided for the given gpt_provider
|
||||
get_api_key(gpt_provider)
|
||||
|
||||
logger.info(f"Model: {model}, Temp: {temperature}, MaxTokens: {max_tokens}, TopP: {top_p}, N: {n}, FrequencyPenalty: {fp}")
|
||||
# Perform text generation using the specified LLM parameters and prompt
|
||||
if 'google' in gpt_provider.lower():
|
||||
try:
|
||||
logger.info("Using Google Gemini Pro text generation model.")
|
||||
response = gemini_text_response(prompt, temperature, top_p, n, max_tokens)
|
||||
return response
|
||||
except Exception as err:
|
||||
logger.error(f"Failed to get response from gemini: {err}")
|
||||
raise err
|
||||
elif 'openai' in gpt_provider.lower():
|
||||
try:
|
||||
logger.info(f"Using OpenAI Model: {model} for text Generation.")
|
||||
response = openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp)
|
||||
return response
|
||||
except Exception as err:
|
||||
logger.error(f"Failed to get response from Openai: {err}")
|
||||
raise err
|
||||
|
||||
except Exception as err:
|
||||
logger.error(f"Failed to read LLM parameters: {err}")
|
||||
raise
|
||||
|
||||
|
||||
def check_gpt_provider(gpt_provider):
|
||||
"""
|
||||
Check if the specified GPT provider matches the environment variable GPT_PROVIDER,
|
||||
assign and export the GPT_PROVIDER value from the config file if missing,
|
||||
and continue.
|
||||
|
||||
Args:
|
||||
gpt_provider (str): The specified GPT provider.
|
||||
|
||||
Raises:
|
||||
ValueError: If both the specified GPT provider and environment variable GPT_PROVIDER are missing.
|
||||
"""
|
||||
env_gpt_provider = os.getenv('GPT_PROVIDER')
|
||||
|
||||
if gpt_provider:
|
||||
os.environ['GPT_PROVIDER'] = gpt_provider
|
||||
elif env_gpt_provider:
|
||||
gpt_provider = env_gpt_provider
|
||||
else:
|
||||
raise ValueError("Both specified GPT provider and environment variable 'GPT_PROVIDER' are missing.")
|
||||
|
||||
if gpt_provider != env_gpt_provider:
|
||||
logger.warning(f"Config: '{gpt_provider}' different to environment variable 'GPT_PROVIDER' '{env_gpt_provider}'")
|
||||
logger.info(f"Using GPT provider: {gpt_provider}")
|
||||
return gpt_provider
|
||||
|
||||
|
||||
|
||||
def get_api_key(gpt_provider):
|
||||
"""
|
||||
Get the API key for the specified GPT provider.
|
||||
|
||||
Args:
|
||||
gpt_provider (str): The specified GPT provider.
|
||||
|
||||
Returns:
|
||||
str: The API key for the specified GPT provider.
|
||||
|
||||
Raises:
|
||||
ValueError: If no API key is found for the specified GPT provider.
|
||||
"""
|
||||
api_key = None
|
||||
|
||||
if gpt_provider.lower() == 'google':
|
||||
api_key = os.getenv('GEMINI_API_KEY')
|
||||
elif gpt_provider.lower() == 'openai':
|
||||
api_key = os.getenv('OPENAI_API_KEY')
|
||||
|
||||
if not api_key:
|
||||
raise ValueError(f"No API key found for the specified GPT provider: '{gpt_provider}'")
|
||||
|
||||
logger.info(f"Using API key for {gpt_provider}")
|
||||
return api_key
|
||||
|
||||
|
||||
|
||||
def read_llm_parameters(config_path: str) -> tuple:
|
||||
"""
|
||||
Read Language Model (LLM) parameters from the configuration file.
|
||||
|
||||
Args:
|
||||
config_path (str): The path to the configuration file.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the LLM parameters (gpt_provider, model, temperature, max_tokens, top_p, n, frequency_penalty).
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If the configuration file is not found.
|
||||
configparser.Error: If there is an error parsing the configuration file.
|
||||
"""
|
||||
try:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(config_path)
|
||||
|
||||
gpt_provider = config.get('llm_options', 'gpt_provider')
|
||||
model = config.get('llm_options', 'model')
|
||||
temperature = config.getfloat('llm_options', 'temperature')
|
||||
max_tokens = config.getint('llm_options', 'max_tokens')
|
||||
top_p = config.getfloat('llm_options', 'top_p')
|
||||
n = config.getint('llm_options', 'n')
|
||||
frequency_penalty = config.getfloat('llm_options', 'frequency_penalty')
|
||||
|
||||
return gpt_provider, model, temperature, max_tokens, top_p, n, frequency_penalty
|
||||
|
||||
except FileNotFoundError:
|
||||
logger.error(f"Configuration file not found: {config_path}")
|
||||
raise
|
||||
except configparser.Error as err:
|
||||
logger.error(f"Error reading LLM parameters from config file: {err}")
|
||||
raise
|
||||
except Exception as err:
|
||||
logger.error(f"An unexpected error occurred: {err}")
|
||||
raise
|
||||
40
lib/gpt_providers/text_generation/mistral_chat_completion.py
Normal file
40
lib/gpt_providers/text_generation/mistral_chat_completion.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from mistralai.client import MistralClient
|
||||
from mistralai.models.chat_completion import ChatMessage
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s-%(levelname)s-%(module)s-%(lineno)d-%(message)s')
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv(Path('../../.env'))
|
||||
|
||||
from tenacity import (
|
||||
retry,
|
||||
stop_after_attempt,
|
||||
wait_random_exponential,
|
||||
) # for exponential backoff
|
||||
|
||||
|
||||
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
|
||||
def mistral_text_response(prompt):
|
||||
""" Common function to get text response from minstral. """
|
||||
api_key = os.environ["MISTRAL_API_KEY"]
|
||||
model = "mistral-medium"
|
||||
|
||||
client = MistralClient(api_key=api_key)
|
||||
|
||||
messages = [
|
||||
ChatMessage(role="user", content=prompt)
|
||||
]
|
||||
|
||||
# No streaming
|
||||
chat_response = client.chat(
|
||||
model=model,
|
||||
messages=messages,
|
||||
)
|
||||
print(chat_response)
|
||||
|
||||
# With streaming
|
||||
for chunk in client.chat_stream(model=model, messages=messages):
|
||||
print(chunk)
|
||||
82
lib/gpt_providers/text_generation/openai_text_gen.py
Normal file
82
lib/gpt_providers/text_generation/openai_text_gen.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
import time #IWish
|
||||
import logging
|
||||
import openai
|
||||
import configparser
|
||||
|
||||
# Configure standard logging
|
||||
logging.basicConfig(level=logging.INFO, format='[%(asctime)s-%(levelname)s-%(module)s-%(lineno)d]- %(message)s')
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from tenacity import (
|
||||
retry,
|
||||
stop_after_attempt,
|
||||
wait_random_exponential,
|
||||
) # for exponential backoff
|
||||
|
||||
|
||||
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
|
||||
def openai_chatgpt(prompt, model, temperature, max_tokens, top_p, n, fp):
|
||||
"""
|
||||
Wrapper function for OpenAI's ChatGPT completion.
|
||||
|
||||
Args:
|
||||
prompt (str): The input text to generate completion for.
|
||||
model (str, optional): Model to be used for the completion. Defaults to "gpt-4-1106-preview".
|
||||
temperature (float, optional): Controls randomness. Lower values make responses more deterministic. Defaults to 0.2.
|
||||
max_tokens (int, optional): Maximum number of tokens to generate. Defaults to 4096
|
||||
top_p (float, optional): Controls diversity. Defaults to 0.9.
|
||||
n (int, optional): Number of completions to generate. Defaults to 1.
|
||||
|
||||
Returns:
|
||||
str: The generated text completion.
|
||||
|
||||
Raises:
|
||||
SystemExit: If an API error, connection error, or rate limit error occurs.
|
||||
"""
|
||||
# Wait for 10 seconds to comply with rate limits
|
||||
for _ in range(5):
|
||||
time.sleep(1)
|
||||
|
||||
try:
|
||||
# Create variables to collect the stream of chunks
|
||||
collected_chunks = []
|
||||
collected_messages = []
|
||||
full_reply_content = None
|
||||
|
||||
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
|
||||
response = client.chat.completions.create(
|
||||
model=model,
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
max_tokens=max_tokens,
|
||||
n=n,
|
||||
top_p=top_p,
|
||||
stream=True,
|
||||
frequency_penalty=fp
|
||||
# Additional parameters can be included here
|
||||
)
|
||||
|
||||
# Iterate through the stream of events
|
||||
for chunk in response:
|
||||
collected_chunks.append(chunk) # save the event response
|
||||
chunk_message = chunk.choices[0].delta.content # extract the message
|
||||
collected_messages.append(chunk_message) # save the message
|
||||
print(chunk.choices[0].delta.content, end = "", flush = True)
|
||||
|
||||
# Clean None in collected_messages
|
||||
collected_messages = [m for m in collected_messages if m is not None]
|
||||
full_reply_content = ''.join([m for m in collected_messages])
|
||||
return full_reply_content
|
||||
|
||||
except openai.APIError as e:
|
||||
logger.error(f"OpenAI API Error: {e}")
|
||||
raise SystemExit from e
|
||||
except openai.APIConnectionError as e:
|
||||
logger.error(f"Failed to connect to OpenAI API: {e}")
|
||||
raise SystemExit from e
|
||||
except openai.RateLimitError as e:
|
||||
logger.error(f"Rate limit exceeded on OpenAI API request: {e}")
|
||||
raise SystemExit from e
|
||||
except Exception as err:
|
||||
logger.error(f"OpenAI error: {err}")
|
||||
raise SystemExit from e
|
||||
Reference in New Issue
Block a user