@@ -83,7 +83,7 @@ class Lightning(SimpleService): ), ] - PRICE = Decimal('0.750') + PRICE = Decimal('0.825') _CALLBACK = ( 'bytedance/sdxl-lightning-4step' @@ -94,8 +94,8 @@ class Recraft(SimpleService): ] payment_rules = { - versions[0].slug: Decimal('20'), - versions[1].slug: Decimal('40'), + versions[0].slug: Decimal('22'), + versions[1].slug: Decimal('44'), } def __init__(self, store: BaseStore) -> None: @@ -14,6 +14,10 @@ from ml_model.tasks import create_new_sd_image, create_sd_image class Stablediffusion(SimpleService): + """ + Stablediffusion Service + contains abstract method make, which makes a generation + """ title = 'StableDiffusion' description = 'Нейросеть, способная генерировать картинки из вашего текста' category = ModelCategory(title='Изображения', slug='images') @@ -42,6 +46,12 @@ class Stablediffusion(SimpleService): type=ModelParameter.TypeChoices.INTRANGE, values={'start': 1, 'end': 100, 'step': 1, 'default': 10}, ), + ModelParameter( + name='Шаги процесса диффузии', + key='steps', + type=ModelParameter.TypeChoices.INTRANGE, + values={'start': 1, 'end': 50, 'step': 1, 'default': 30}, + ), ModelParameter( name='Количество изображений', key='num_images', @@ -94,64 +104,56 @@ class Stablediffusion(SimpleService): name='Соотношение сторон', key='aspect_ratio', type=ModelParameter.TypeChoices.LIST, - values={'availables': ['1:1', '16:9', '9:16'], 'default': '1:1'}, + values={ + 'availables': + [ + '1:1', + '16:9', + '9:16', + ], + 'default': '1:1' + }, + ), + ModelParameter( + name='Соотношение сторон', + key='aspect_ratio', + type=ModelParameter.TypeChoices.LIST, + values={ + 'availables': + [ + '1:1', + '4:3', + '3:4', + '3:2', + '16:9', + '9:16', + '24:10', + '10:24' + ], + 'default': '1:1' + }, ), ] - price = Decimal('2') + TOKEN_PRICE = Decimal('11') _API_KEY = settings.STABLE_DIFFUSION_API_KEY - TOKEN_PAYMENT_RULES = { - 15: { - 512 * 512: Decimal('2'), - 512 * 768: Decimal('2.4'), - 512 * 1024: Decimal('2.7'), - 768 * 768: Decimal('2.9'), - 768 * 1024: Decimal('3.4'), - 1024 * 1024: Decimal('4'), - }, - 30: { - 512 * 512: Decimal('6.2'), - 512 * 768: Decimal('6.6'), - 512 * 1024: Decimal('6.9'), - 768 * 768: Decimal('7.2'), - 768 * 1024: Decimal('7.5'), - 1024 * 1024: Decimal('8'), - }, - 50: { - 512 * 512: Decimal('9'), - 512 * 768: Decimal('9.2'), - 512 * 1024: Decimal('9.3'), - 768 * 768: Decimal('9.4'), - 768 * 1024: Decimal('9.6'), - 1024 * 1024: Decimal('10'), - }, - } - def calculate_price(self, input_message: Message) -> Decimal: - steps = input_message.info.get('steps', 30) - width, height = input_message.info.get('format_image', '1024x1024').split('x') - pixel_size = int(width) * int(height) - important_steps = list(self.TOKEN_PAYMENT_RULES.keys()) - closest_number = min(important_steps, key=lambda x: abs(int(x) - steps)) - price_range = self.TOKEN_PAYMENT_RULES[closest_number] - important_sizes = list(price_range.keys()) - closest_size = min(important_sizes, key=lambda x: abs(int(x) - pixel_size)) if ( input_message.info.get('version') or input_message.info.get('engine', 'sd3') ) == 'sd3': - gen_price = Decimal('65') + return Decimal('71.5') elif ( input_message.info.get('version') or input_message.info.get('engine', 'sd3') ) == 'sd3-turbo': - gen_price = Decimal('40') - else: - gen_price = Decimal(price_range[closest_size]) * self.price - return gen_price + return Decimal('44') + steps = input_message.info.get('steps', 30) + default_price = Decimal('0.9') * self.TOKEN_PRICE + return default_price if steps <= 30 else default_price * Decimal((steps / 30)) def save_results( - self, input_prompt: str, r: list[BytesIO], t: timedelta, save: bool = True + self, input_prompt: str, r: list[BytesIO], t: timedelta, save: bool = True ) -> list[Message]: out: list[Message] = [] for obj in r: @@ -171,15 +173,25 @@ class Stablediffusion(SimpleService): return out def make(self, input_message: Message, save: bool = True) -> list[Message]: + aspect_rations = { + '1:1': (1024, 1024), + '4:3': (1152, 896), + '3:4': (896, 1152), + '3:2': (1216, 832), + '16:9': (1344, 768), + '9:16': (768, 1344), + '24:10': (1536, 640), + '10:24': (640, 1536) + } start_time = time.time() info = input_message.info.copy() model_name = info.get('version') or info.get('engine', 'sd3') formatter = { 'width': int( - input_message.info.get('format_image', '1024x1024').split('x')[0] + aspect_rations[input_message.info.get('aspect_ratio', '1:1')][0] ), 'height': int( - input_message.info.get('format_image', '1024x1024').split('x')[1] + aspect_rations[input_message.info.get('aspect_ratio', '1:1')][1] ), } translated_prompt = self.translate_prompt(input_message.content)