Remove hardcoded 'magic values'

duckdoom4 2 years ago
parent 5de2e79b3b
commit ac11d9f2a4

@ -5,8 +5,9 @@ import re
import discord
from models.deepl_model import TranslationModel
from services.moderations_service import ModerationOptions
from services.usage_service import UsageService
from models.openai_model import Model
from models.openai_model import ImageSize, Model, ModelLimits, Models, Mode
from services.environment_service import EnvService
usage_service = UsageService(Path(os.environ.get("DATA_DIR", os.getcwd())))
@ -34,26 +35,27 @@ class Settings_autocompleter:
): # Behaves a bit weird if you go back and edit the parameter without typing in a new command
"""gets valid values for the value option"""
values = {
"max_conversation_length": [str(num) for num in range(1, 500, 2)],
"num_images": [str(num) for num in range(1, 4 + 1)],
"mode": ["temperature", "top_p"],
"model": ["text-davinci-003", "text-curie-001"],
"max_conversation_length": [str(num) for num in range(ModelLimits.MIN_CONVERSATION_LENGTH, ModelLimits.MAX_CONVERSATION_LENGTH + 1, 2)],
"num_images": [str(num) for num in range(ModelLimits.MIN_NUM_IMAGES, ModelLimits.MAX_NUM_IMAGES + 1)],
"mode": Mode.ALL_MODES,
"model": Models.TEXT_MODELS,
"low_usage_mode": ["True", "False"],
"image_size": ["256x256", "512x512", "1024x1024"],
"image_size": ImageSize.ALL_SIZES,
"summarize_conversation": ["True", "False"],
"welcome_message_enabled": ["True", "False"],
"num_static_conversation_items": [str(num) for num in range(5, 20 + 1)],
"num_conversation_lookback": [str(num) for num in range(5, 15 + 1)],
"summarize_threshold": [str(num) for num in range(800, 3500, 50)],
"num_static_conversation_items": [str(num) for num in range(ModelLimits.MIN_NUM_STATIC_CONVERSATION_ITEMS, ModelLimits.MAX_NUM_STATIC_CONVERSATION_ITEMS + 1)],
"num_conversation_lookback": [str(num) for num in range(ModelLimits.MIN_NUM_CONVERSATION_LOOKBACK, ModelLimits.MAX_NUM_CONVERSATION_LOOKBACK + 1)],
"summarize_threshold": [str(num) for num in range(ModelLimits.MIN_SUMMARIZE_THRESHOLD, ModelLimits.MAX_SUMMARIZE_THRESHOLD + 1, 50)],
"type": ["warn", "delete"],
}
for parameter in values:
if parameter == ctx.options["parameter"]:
return [
value
for value in values[ctx.options["parameter"]]
if value.startswith(ctx.value.lower())
]
options = values.get(ctx.options["parameter"], [])
if options:
return [
value
for value in options
if value.startswith(ctx.value.lower())
]
await ctx.interaction.response.defer() # defer so the autocomplete in int values doesn't error but rather just says not found
return []
@ -64,7 +66,7 @@ class Settings_autocompleter:
print(f"The value is {ctx.value}")
return [
value
for value in ["warn", "delete", "reset"]
for value in ModerationOptions.OPTIONS
if value.startswith(ctx.value.lower())
]

@ -18,8 +18,10 @@ from discord import File
class Mode:
TOP_P = "top_p"
TEMPERATURE = "temperature"
TOP_P = "top_p"
ALL_MODES = [TEMPERATURE, TOP_P]
class Models:
@ -40,11 +42,57 @@ class Models:
EDIT = "text-davinci-edit-001"
CODE_EDIT = "code-davinci-edit-001"
# Model collections
TEXT_MODELS = [DAVINCI, CURIE, BABBAGE, ADA, CODE_DAVINCI, CODE_CUSHMAN]
EDIT_MODELS = [EDIT, CODE_EDIT]
DEFAULT = DAVINCI
LOW_USAGE_MODEL = CURIE
class ImageSize:
LARGE = "1024x1024"
MEDIUM = "512x512"
SMALL = "256x256"
MEDIUM = "512x512"
LARGE = "1024x1024"
ALL_SIZES = [SMALL, MEDIUM, LARGE]
class ModelLimits:
MIN_TOKENS = 15
MAX_TOKENS = 4096
MIN_CONVERSATION_LENGTH = 1
MAX_CONVERSATION_LENGTH = 500
MIN_SUMMARIZE_THRESHOLD = 800
MAX_SUMMARIZE_THRESHOLD = 3500
MIN_NUM_IMAGES = 1
MAX_NUM_IMAGES = 4
MIN_NUM_STATIC_CONVERSATION_ITEMS = 5
MAX_NUM_STATIC_CONVERSATION_ITEMS = 20
MIN_NUM_CONVERSATION_LOOKBACK = 5
MAX_NUM_CONVERSATION_LOOKBACK = 15
MIN_TEMPERATURE = 0.0
MAX_TEMPERATURE = 2.0
MIN_TOP_P = 0.0
MAX_TOP_P = 1.0
MIN_PRESENCE_PENALTY = -2.0
MAX_PRESENCE_PENALTY = 2.0
MIN_FREQUENCY_PENALTY = -2.0
MAX_FREQUENCY_PENALTY = 2.0
MIN_BEST_OF = 1
MAX_BEST_OF = 3
MIN_PROMPT_MIN_LENGTH = 10
MAX_PROMPT_MIN_LENGTH = 4096
class Model:
@ -61,7 +109,7 @@ class Model:
self._best_of = 1 # Number of responses to compare the loglikelihoods of
self._prompt_min_length = 8
self._max_conversation_length = 100
self._model = Models.DAVINCI
self._model = Models.DEFAULT
self._low_usage_mode = False
self.usage_service = usage_service
self.DAVINCI_ROLES = ["admin", "Admin", "GPT", "gpt"]
@ -105,11 +153,11 @@ class Model:
@num_static_conversation_items.setter
def num_static_conversation_items(self, value):
value = int(value)
if value < 3:
raise ValueError("num_static_conversation_items must be >= 3")
if value > 20:
if value < ModelLimits.MIN_NUM_STATIC_CONVERSATION_ITEMS:
raise ValueError(f"Number of static conversation items must be >= {ModelLimits.MIN_NUM_STATIC_CONVERSATION_ITEMS}")
if value > ModelLimits.MAX_NUM_STATIC_CONVERSATION_ITEMS:
raise ValueError(
"num_static_conversation_items must be <= 20, this is to ensure reliability and reduce token wastage!"
f"Number of static conversation items must be <= {ModelLimits.MAX_NUM_STATIC_CONVERSATION_ITEMS}, this is to ensure reliability and reduce token wastage!"
)
self._num_static_conversation_items = value
@ -120,11 +168,11 @@ class Model:
@num_conversation_lookback.setter
def num_conversation_lookback(self, value):
value = int(value)
if value < 3:
raise ValueError("num_conversation_lookback must be >= 3")
if value > 15:
if value < ModelLimits.MIN_NUM_CONVERSATION_LOOKBACK:
raise ValueError(f"Number of conversations to look back on must be >= {ModelLimits.MIN_NUM_CONVERSATION_LOOKBACK}")
if value > ModelLimits.MAX_NUM_CONVERSATION_LOOKBACK:
raise ValueError(
"num_conversation_lookback must be <= 15, this is to ensure reliability and reduce token wastage!"
f"Number of conversations to look back on must be <= {ModelLimits.MIN_NUM_CONVERSATION_LOOKBACK}, this is to ensure reliability and reduce token wastage!"
)
self._num_conversation_lookback = value
@ -139,7 +187,7 @@ class Model:
elif value.lower() == "false":
self._welcome_message_enabled = False
else:
raise ValueError("Value must be either true or false!")
raise ValueError("Value must be either `true` or `false`!")
@property
def summarize_threshold(self):
@ -148,9 +196,9 @@ class Model:
@summarize_threshold.setter
def summarize_threshold(self, value):
value = int(value)
if value < 800 or value > 4000:
if value < ModelLimits.MIN_SUMMARIZE_THRESHOLD or value > ModelLimits.MAX_SUMMARIZE_THRESHOLD:
raise ValueError(
"Summarize threshold cannot be greater than 4000 or less than 800!"
f"Summarize threshold should be a number between {ModelLimits.MIN_SUMMARIZE_THRESHOLD} and {ModelLimits.MAX_SUMMARIZE_THRESHOLD}!"
)
self._summarize_threshold = value
@ -166,7 +214,7 @@ class Model:
elif value.lower() == "false":
value = False
else:
raise ValueError("Value must be either true or false!")
raise ValueError("Value must be either `true` or `false`!")
self._summarize_conversations = value
@property
@ -175,11 +223,11 @@ class Model:
@image_size.setter
def image_size(self, value):
if value in ImageSize.__dict__.values():
if value in ImageSize.ALL_SIZES:
self._image_size = value
else:
raise ValueError(
"Image size must be one of the following: SMALL(256x256), MEDIUM(512x512), LARGE(1024x1024)"
f"Image size must be one of the following: {ImageSize.ALL_SIZES}"
)
@property
@ -189,8 +237,8 @@ class Model:
@num_images.setter
def num_images(self, value):
value = int(value)
if value > 4 or value <= 0:
raise ValueError("num_images must be less than 4 and at least 1.")
if value < ModelLimits.MIN_NUM_IMAGES or value > ModelLimits.MAX_NUM_IMAGES:
raise ValueError(f"Number of images to generate should be a number between {ModelLimits.MIN_NUM_IMAGES} and {ModelLimits.MAX_NUM_IMAGES}!")
self._num_images = value
@property
@ -205,14 +253,14 @@ class Model:
elif value.lower() == "false":
value = False
else:
raise ValueError("Value must be either true or false!")
raise ValueError("Value must be either `true` or `false`!")
if value:
self._model = Models.CURIE
self._model = Models.LOW_USAGE_MODEL
self.max_tokens = 1900
self.model_max_tokens = 1000
else:
self._model = Models.DAVINCI
self._model = Models.DEFAULT
self.max_tokens = 4000
self.model_max_tokens = 4024
@ -222,10 +270,8 @@ class Model:
@model.setter
def model(self, model):
if model not in [Models.DAVINCI, Models.CURIE]:
raise ValueError(
"Invalid model, must be text-davinci-003 or text-curie-001"
)
if model not in Models.TEXT_MODELS:
raise ValueError(f"Invalid model, must be one of: {Models.TEXT_MODELS}")
self._model = model
@property
@ -235,11 +281,11 @@ class Model:
@max_conversation_length.setter
def max_conversation_length(self, value):
value = int(value)
if value < 1:
raise ValueError("Max conversation length must be greater than 1")
if value > 500:
if value < ModelLimits.MIN_CONVERSATION_LENGTH:
raise ValueError(f"Max conversation length must be greater than {ModelLimits.MIN_CONVERSATION_LENGTH}")
if value > ModelLimits.MAX_CONVERSATION_LENGTH:
raise ValueError(
"Max conversation length must be less than 500, this will start using credits quick."
f"Max conversation length must be less than {ModelLimits.MIN_CONVERSATION_LENGTH}, this will start using credits quick."
)
self._max_conversation_length = value
@ -249,14 +295,17 @@ class Model:
@mode.setter
def mode(self, value):
if value not in [Mode.TOP_P, Mode.TEMPERATURE]:
raise ValueError("mode must be either 'top_p' or 'temperature'")
if value not in Mode.ALL_MODES:
raise ValueError(f"Mode must be one of: {Mode.ALL_MODES}")
if value == Mode.TOP_P:
self._top_p = 0.1
self._temp = 0.7
elif value == Mode.TEMPERATURE:
self._top_p = 0.9
self._temp = 0.6
else:
raise ValueError(f"Unknown mode: {value}")
self._mode = value
@ -267,10 +316,9 @@ class Model:
@temp.setter
def temp(self, value):
value = float(value)
if value < 0 or value > 2:
if value < ModelLimits.MIN_TEMPERATURE or value > ModelLimits.MAX_TEMPERATURE:
raise ValueError(
"temperature must be greater than 0 and less than 2, it is currently "
+ str(value)
f"Temperature must be between {ModelLimits.MIN_TEMPERATURE} and {ModelLimits.MAX_TEMPERATURE}, it is currently: {value}"
)
self._temp = value
@ -282,10 +330,9 @@ class Model:
@top_p.setter
def top_p(self, value):
value = float(value)
if value < 0 or value > 1:
if value < ModelLimits.MIN_TOP_P or value > ModelLimits.MAX_TOP_P:
raise ValueError(
"top_p must be greater than 0 and less than 1, it is currently "
+ str(value)
f"Top P must be between {ModelLimits.MIN_TOP_P} and {ModelLimits.MAX_TOP_P}, it is currently: {value}"
)
self._top_p = value
@ -296,10 +343,9 @@ class Model:
@max_tokens.setter
def max_tokens(self, value):
value = int(value)
if value < 15 or value > 4096:
if value < ModelLimits.MIN_TOKENS or value > ModelLimits.MAX_TOKENS:
raise ValueError(
"max_tokens must be greater than 15 and less than 4096, it is currently "
+ str(value)
f"Max tokens must be between {ModelLimits.MIN_TOKENS} and {ModelLimits.MAX_TOKENS}, it is currently: {value}"
)
self._max_tokens = value
@ -309,9 +355,10 @@ class Model:
@presence_penalty.setter
def presence_penalty(self, value):
if int(value) < 0:
value = float(value)
if value < ModelLimits.MIN_PRESENCE_PENALTY or value > ModelLimits.MAX_PRESENCE_PENALTY:
raise ValueError(
"presence_penalty must be greater than 0, it is currently " + str(value)
f"Presence penalty must be between {ModelLimits.MIN_PRESENCE_PENALTY} and {ModelLimits.MAX_PRESENCE_PENALTY}, it is currently: {value}"
)
self._presence_penalty = value
@ -321,10 +368,10 @@ class Model:
@frequency_penalty.setter
def frequency_penalty(self, value):
if int(value) < 0:
value = float(value)
if value < ModelLimits.MIN_FREQUENCY_PENALTY or value > ModelLimits.MAX_FREQUENCY_PENALTY:
raise ValueError(
"frequency_penalty must be greater than 0, it is currently "
+ str(value)
f"Frequency penalty must be greater between {ModelLimits.MIN_FREQUENCY_PENALTY} and {ModelLimits.MAX_FREQUENCY_PENALTY}, it is currently: {value}"
)
self._frequency_penalty = value
@ -335,10 +382,9 @@ class Model:
@best_of.setter
def best_of(self, value):
value = int(value)
if value < 1 or value > 3:
if value < ModelLimits.MIN_BEST_OF or value > ModelLimits.MAX_BEST_OF:
raise ValueError(
"best_of must be greater than 0 and ideally less than 3 to save tokens, it is currently "
+ str(value)
f"Best of must be between {ModelLimits.MIN_BEST_OF} and {ModelLimits.MAX_BEST_OF}, it is currently: {value}\nNote that increasing the value of this parameter will act as a multiplier on the number of tokens requested!"
)
self._best_of = value
@ -349,10 +395,9 @@ class Model:
@prompt_min_length.setter
def prompt_min_length(self, value):
value = int(value)
if value < 10 or value > 4096:
if value < ModelLimits.MIN_PROMPT_MIN_LENGTH or value > ModelLimits.MAX_PROMPT_MIN_LENGTH:
raise ValueError(
"prompt_min_length must be greater than 10 and less than 4096, it is currently "
+ str(value)
f"Minimal prompt length must be between {ModelLimits.MIN_PROMPT_MIN_LENGTH} and {ModelLimits.MAX_PROMPT_MIN_LENGTH}, it is currently: {value}"
)
self._prompt_min_length = value
@ -553,11 +598,10 @@ class Model:
# Validate that all the parameters are in a good state before we send the request
if len(prompt) < self.prompt_min_length:
raise ValueError(
"Prompt must be greater than 8 characters, it is currently "
+ str(len(prompt))
f"Prompt must be greater than {self.prompt_min_length} characters, it is currently: {len(prompt)} characters"
)
print("The prompt about to be sent is " + prompt)
print(f"The prompt about to be sent is {prompt}")
print(
f"Overrides -> temp:{temp_override}, top_p:{top_p_override} frequency:{frequency_penalty_override}, presence:{presence_penalty_override}"
)
@ -599,7 +643,7 @@ class Model:
async with aiohttp.ClientSession() as session:
payload = {
"model": Models.CURIE,
"model": Models.LOW_USAGE_MODEL,
"prompt": "test.",
"temperature": 1,
"top_p": 1,

@ -19,6 +19,13 @@ class ModerationResult:
DELETE = "delete"
NONE = "none"
class ModerationOptions:
WARN = "warn"
DELETE = "delete"
RESET = "reset"
OPTIONS = [WARN, DELETE, RESET]
class ThresholdSet:
def __init__(self, h_t, hv_t, sh_t, s_t, sm_t, v_t, vg_t):

Loading…
Cancel
Save