novelai-python 0.7.5__tar.gz → 0.7.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. {novelai_python-0.7.5 → novelai_python-0.7.6}/PKG-INFO +1 -1
  2. {novelai_python-0.7.5 → novelai_python-0.7.6}/pyproject.toml +1 -1
  3. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/_enum.py +196 -43
  4. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate_image/__init__.py +58 -53
  5. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/image_metadata/__init__.py +2 -2
  6. {novelai_python-0.7.5 → novelai_python-0.7.6}/LICENSE +0 -0
  7. {novelai_python-0.7.5 → novelai_python-0.7.6}/NOTICE.MD +0 -0
  8. {novelai_python-0.7.5 → novelai_python-0.7.6}/README.md +0 -0
  9. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/__init__.py +0 -0
  10. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_enum.py +0 -0
  11. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_exceptions.py +0 -0
  12. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/__init__.py +0 -0
  13. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/ai/__init__.py +0 -0
  14. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/ai/generate.py +0 -0
  15. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/ai/generate_image.py +0 -0
  16. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/ai/generate_stream.py +0 -0
  17. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/ai/generate_voice.py +0 -0
  18. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/ai/upscale.py +0 -0
  19. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/schema.py +0 -0
  20. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/user/__init__.py +0 -0
  21. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/user/information.py +0 -0
  22. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/user/login.py +0 -0
  23. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/_response/user/subscription.py +0 -0
  24. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/credential/ApiToken.py +0 -0
  25. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/credential/JwtToken.py +0 -0
  26. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/credential/UserAuth.py +0 -0
  27. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/credential/__init__.py +0 -0
  28. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/credential/_base.py +0 -0
  29. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/__init__.py +0 -0
  30. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/LICENSE +0 -0
  31. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/__init__.py +0 -0
  32. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/_const.py +0 -0
  33. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/_cost.py +0 -0
  34. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/augment_image/__init__.py +0 -0
  35. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/augment_image/_enum.py +0 -0
  36. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate/__init__.py +0 -0
  37. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate/_const.py +0 -0
  38. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate/_enum.py +0 -0
  39. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate/_schema.py +0 -0
  40. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate/themes.json +0 -0
  41. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate_image/schema.py +0 -0
  42. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate_image/suggest_tags.py +0 -0
  43. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate_stream.py +0 -0
  44. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate_voice/__init__.py +0 -0
  45. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/generate_voice/_enum.py +0 -0
  46. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/ai/upscale.py +0 -0
  47. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/schema.py +0 -0
  48. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/user/__init__.py +0 -0
  49. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/user/information.py +0 -0
  50. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/user/login.py +0 -0
  51. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/sdk/user/subscription.py +0 -0
  52. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/server.py +0 -0
  53. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tokenizer/__init__.py +0 -0
  54. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tokenizer/clip_simple_tokenizer.py +0 -0
  55. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tokenizer/nerdstash_v1.model +0 -0
  56. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tokenizer/nerdstash_v2.model +0 -0
  57. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tokenizer/novelai.model +0 -0
  58. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tokenizer/novelai_v2.model +0 -0
  59. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/__init__.py +0 -0
  60. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/image_metadata/bch_utils.py +0 -0
  61. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/image_metadata/lsb_extractor.py +0 -0
  62. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/image_metadata/lsb_injector.py +0 -0
  63. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/paint_mask/__init__.py +0 -0
  64. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/random_prompt/__init__.py +0 -0
  65. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/random_prompt/generate_scene_composition.py +0 -0
  66. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/random_prompt/generate_scene_tags.py +0 -0
  67. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/tool/random_prompt/generate_tags.py +0 -0
  68. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/utils/__init__.py +0 -0
  69. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/utils/encode.py +0 -0
  70. {novelai_python-0.7.5 → novelai_python-0.7.6}/src/novelai_python/utils/useful.py +0 -0
  71. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/__init__.py +0 -0
  72. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_generate_voice.py +0 -0
  73. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_random_prompt.py +0 -0
  74. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_server.py +0 -0
  75. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_server_run.py +0 -0
  76. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_tokenizer.py +0 -0
  77. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_upscale.py +0 -0
  78. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_user_information.py +0 -0
  79. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_user_login.py +0 -0
  80. {novelai_python-0.7.5 → novelai_python-0.7.6}/tests/test_user_subscription.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: novelai-python
3
- Version: 0.7.5
3
+ Version: 0.7.6
4
4
  Summary: NovelAI Python Binding With Pydantic
5
5
  Author-Email: sudoskys <coldlando@hotmail.com>
6
6
  License: Apache License 2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "novelai-python"
3
- version = "0.7.5"
3
+ version = "0.7.6"
4
4
  description = "NovelAI Python Binding With Pydantic"
5
5
  authors = [
6
6
  { name = "sudoskys", email = "coldlando@hotmail.com" },
@@ -92,6 +92,9 @@ class Resolution(Enum):
92
92
 
93
93
  class Model(Enum):
94
94
  NAI_DIFFUSION_4_CURATED_PREVIEW = "nai-diffusion-4-curated-preview"
95
+ NAI_DIFFUSION_4_FULL = "nai-diffusion-4-full"
96
+ NAI_DIFFUSION_4_FULL_INPAINTING = "nai-diffusion-4-full-inpainting"
97
+ NAI_DIFFUSION_4_CURATED_INPAINTING = "nai-diffusion-4-curated-inpainting"
95
98
 
96
99
  NAI_DIFFUSION_3 = "nai-diffusion-3"
97
100
  NAI_DIFFUSION_3_INPAINTING = "nai-diffusion-3-inpainting"
@@ -151,6 +154,8 @@ PROMOTION = {
151
154
  "Stable Diffusion XL C8704949": Model.NAI_DIFFUSION_FURRY_3,
152
155
  "Stable Diffusion XL 37C2B166": Model.NAI_DIFFUSION_FURRY_3,
153
156
  "Stable Diffusion XL 9CC2F394": Model.NAI_DIFFUSION_FURRY_3,
157
+ 'NovelAI Diffusion V4 4F49EC75': Model.NAI_DIFFUSION_4_FULL,
158
+ 'NovelAI Diffusion V4 CA4B7203': Model.NAI_DIFFUSION_4_FULL,
154
159
  }
155
160
 
156
161
  ModelTypeAlias = Optional[Union[Model, str]]
@@ -171,6 +176,7 @@ class SupportCondition:
171
176
  v4Prompts: bool
172
177
  smea: bool
173
178
  text: bool
179
+ dynamicThresholding: bool
174
180
 
175
181
 
176
182
  def get_supported_params(model: Model):
@@ -201,7 +207,8 @@ def get_supported_params(model: Model):
201
207
  characterPrompts=False,
202
208
  v4Prompts=False,
203
209
  smea=True,
204
- text=False
210
+ text=False,
211
+ dynamicThresholding=True
205
212
  )
206
213
  if model in [Model.NAI_DIFFUSION_2]:
207
214
  return SupportCondition(
@@ -215,7 +222,8 @@ def get_supported_params(model: Model):
215
222
  characterPrompts=False,
216
223
  v4Prompts=False,
217
224
  smea=True,
218
- text=False
225
+ text=False,
226
+ dynamicThresholding=True
219
227
  )
220
228
  if model in [
221
229
  Model.NAI_DIFFUSION_XL,
@@ -235,21 +243,29 @@ def get_supported_params(model: Model):
235
243
  characterPrompts=False,
236
244
  v4Prompts=False,
237
245
  smea=True,
238
- text=False
246
+ text=False,
247
+ dynamicThresholding=True
239
248
  )
240
- if model in [Model.CUSTOM, Model.NAI_DIFFUSION_4_CURATED_PREVIEW]:
249
+ if model in [
250
+ Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
251
+ Model.NAI_DIFFUSION_4_CURATED_INPAINTING,
252
+ Model.CUSTOM,
253
+ Model.NAI_DIFFUSION_4_FULL,
254
+ Model.NAI_DIFFUSION_4_FULL_INPAINTING,
255
+ ]:
241
256
  return SupportCondition(
242
257
  controlnet=False,
243
258
  vibetransfer=False,
244
- scaleMax=10,
259
+ scaleMax=20,
245
260
  negativePromptGuidance=True,
246
261
  noiseSchedule=True,
247
262
  inpainting=True,
248
- cfgDelay=False,
263
+ cfgDelay=True,
249
264
  characterPrompts=True,
250
265
  v4Prompts=True,
251
266
  smea=False,
252
- text=True
267
+ text=True,
268
+ dynamicThresholding=False
253
269
  )
254
270
  return SupportCondition(
255
271
  controlnet=False,
@@ -262,7 +278,8 @@ def get_supported_params(model: Model):
262
278
  characterPrompts=False,
263
279
  v4Prompts=False,
264
280
  smea=False,
265
- text=False
281
+ text=False,
282
+ dynamicThresholding=False
266
283
  )
267
284
 
268
285
 
@@ -272,13 +289,31 @@ class Modifier(object):
272
289
  suffix: str
273
290
 
274
291
 
292
+ def find_model_by_hashcode(hashcode: str) -> ModelTypeAlias:
293
+ if "NovelAI Diffusion V4" in hashcode:
294
+ return PROMOTION.get(hashcode, Model.NAI_DIFFUSION_4_CURATED_PREVIEW)
295
+ return PROMOTION.get(hashcode, None)
296
+
297
+
275
298
  def get_modifiers(model: Model) -> Modifier:
276
299
  """
277
300
  Get modifiers from model
278
301
  :param model:
279
302
  :return:
280
303
  """
281
- if model in [Model.CUSTOM, Model.NAI_DIFFUSION_4_CURATED_PREVIEW]:
304
+ if model in [
305
+ Model.CUSTOM,
306
+ Model.NAI_DIFFUSION_4_FULL,
307
+ Model.NAI_DIFFUSION_4_FULL_INPAINTING,
308
+ ]:
309
+ return Modifier(
310
+ qualityTags="",
311
+ suffix=", no text, best quality, very aesthetic, absurdres"
312
+ )
313
+ if model in [
314
+ Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
315
+ Model.NAI_DIFFUSION_4_CURATED_INPAINTING,
316
+ ]:
282
317
  return Modifier(
283
318
  qualityTags="",
284
319
  suffix=", rating:general, best quality, very aesthetic, absurdres"
@@ -310,7 +345,37 @@ def get_modifiers(model: Model) -> Modifier:
310
345
  )
311
346
 
312
347
 
313
- def get_supported_noise_schedule(sample_type: Sampler) -> List[NoiseSchedule]:
348
+ def get_supported_noise_schedule(sample_type: Sampler, model: Model) -> List[NoiseSchedule]:
349
+ """
350
+ Get supported noise schedule for a given sample type and model
351
+ :param sample_type: Sampler
352
+ :param model: Model
353
+ :return: List[NoiseSchedule]
354
+ """
355
+ noise_schedule = get_sampler_supported_noise_schedule(sample_type)
356
+ schedules = filter_by_model_noise_schedule(model, noise_schedule)
357
+ return schedules
358
+
359
+
360
+ def filter_by_model_noise_schedule(model: Model, noise_schedule: List[NoiseSchedule]) -> List[NoiseSchedule]:
361
+ """
362
+ Filter noise schedule by model
363
+ :param model:
364
+ :param noise_schedule:
365
+ :return:
366
+ """
367
+ # 只有Novelai4系列不支持Native
368
+ if model in [
369
+ Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
370
+ Model.NAI_DIFFUSION_4_FULL,
371
+ Model.NAI_DIFFUSION_4_FULL_INPAINTING,
372
+ Model.NAI_DIFFUSION_4_CURATED_INPAINTING
373
+ ]:
374
+ return [schedule for schedule in noise_schedule if schedule != NoiseSchedule.NATIVE]
375
+ return noise_schedule
376
+
377
+
378
+ def get_sampler_supported_noise_schedule(sample_type: Sampler) -> List[NoiseSchedule]:
314
379
  """
315
380
  Get supported noise schedule for a given sample type
316
381
  :param sample_type: Sampler
@@ -384,6 +449,9 @@ def get_model_group(model: ModelTypeAlias) -> ModelGroups:
384
449
  "nai-diffusion-furry-3": ModelGroups.STABLE_DIFFUSION_XL_FURRY,
385
450
  "nai-diffusion-furry-3-inpainting": ModelGroups.STABLE_DIFFUSION_XL_FURRY,
386
451
  "nai-diffusion-4-curated-preview": ModelGroups.V4,
452
+ 'nai-diffusion-4-full': ModelGroups.V4,
453
+ 'nai-diffusion-4-full-inpainting': ModelGroups.V4,
454
+ 'nai-diffusion-4-curated-inpainting': ModelGroups.V4
387
455
  }
388
456
  return mapping.get(model, ModelGroups.STABLE_DIFFUSION)
389
457
 
@@ -404,67 +472,152 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
404
472
  Model.SAFE_DIFFUSION_INPAINTING,
405
473
  ]:
406
474
  prompts = [
407
- UcPrompt(category="heavy", name="lowQualityPlusBadAnatomy",
408
- text="lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"),
409
- UcPrompt(category="light", name="lowQuality",
410
- text="lowres, text, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"),
411
- UcPrompt(category="none", name="none", text="lowres"),
475
+ UcPrompt(
476
+ category="heavy",
477
+ name="lowQualityPlusBadAnatomy",
478
+ text="lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
479
+ ),
480
+ UcPrompt(
481
+ category="light",
482
+ name="lowQuality",
483
+ text="lowres, text, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
484
+ ),
485
+ UcPrompt(
486
+ category="none",
487
+ name="none",
488
+ text="lowres"
489
+ ),
412
490
  ]
413
491
  elif model in [
414
492
  Model.NAI_DIFFUSION_FURRY,
415
493
  Model.FURRY_DIFFUSION_INPAINTING,
416
494
  ]:
417
495
  prompts = [
418
- UcPrompt(category="light", name="lowQuality",
419
- text="worst quality, low quality, what has science done, what, nightmare fuel, eldritch horror, where is your god now, why"),
420
- UcPrompt(category="heavy", name="badAnatomy",
421
- text="{worst quality}, low quality, distracting watermark, [nightmare fuel], {{unfinished}}, deformed, outline, pattern, simple background"),
422
- UcPrompt(category="none", name="none", text="low res"),
496
+ UcPrompt(
497
+ category="light",
498
+ name="lowQuality",
499
+ text="worst quality, low quality, what has science done, what, nightmare fuel, eldritch horror, where is your god now, why"
500
+ ),
501
+ UcPrompt(
502
+ category="heavy",
503
+ name="badAnatomy",
504
+ text="{worst quality}, low quality, distracting watermark, [nightmare fuel], {{unfinished}}, deformed, outline, pattern, simple background"
505
+ ),
506
+ UcPrompt(
507
+ category="none",
508
+ name="none",
509
+ text="low res"
510
+ ),
423
511
  ]
424
512
  elif model in [
425
513
  Model.NAI_DIFFUSION_2,
426
514
  ]:
427
515
  prompts = [
428
- UcPrompt(category="heavy", name="heavy",
429
- text="lowres, bad, text, error, missing, extra, fewer, cropped, jpeg artifacts, worst quality, bad quality, watermark, displeasing, unfinished, chromatic aberration, scan, scan artifacts"),
430
- UcPrompt(category="light", name="light",
431
- text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"),
432
- UcPrompt(category="none", name="none", text="lowres"),
516
+ UcPrompt(
517
+ category="heavy",
518
+ name="heavy",
519
+ text="lowres, bad, text, error, missing, extra, fewer, cropped, jpeg artifacts, worst quality, bad quality, watermark, displeasing, unfinished, chromatic aberration, scan, scan artifacts"
520
+ ),
521
+ UcPrompt(
522
+ category="light",
523
+ name="light",
524
+ text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"
525
+ ),
526
+ UcPrompt(
527
+ category="none",
528
+ name="none",
529
+ text="lowres"
530
+ ),
433
531
  ]
434
532
  elif model in [
435
533
  Model.NAI_DIFFUSION_3,
436
534
  Model.NAI_DIFFUSION_3_INPAINTING,
437
535
  ]:
438
536
  prompts = [
439
- UcPrompt(category="heavy", name="heavy",
440
- text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]"),
441
- UcPrompt(category="light", name="light",
442
- text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"),
443
- UcPrompt(category="human", name="humanFocus",
444
- text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract], bad anatomy, bad hands, @_@, mismatched pupils, heart-shaped pupils, glowing eyes"),
445
- UcPrompt(category="none", name="none", text="lowres"),
537
+ UcPrompt(
538
+ category="heavy",
539
+ name="heavy",
540
+ text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]"
541
+ ),
542
+ UcPrompt(
543
+ category="light",
544
+ name="light",
545
+ text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"
546
+ ),
547
+ UcPrompt(
548
+ category="human",
549
+ name="humanFocus",
550
+ text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract], bad anatomy, bad hands, @_@, mismatched pupils, heart-shaped pupils, glowing eyes"
551
+ ),
552
+ UcPrompt(
553
+ category="none",
554
+ name="none",
555
+ text="lowres"
556
+ ),
446
557
  ]
447
558
  elif model in [
448
559
  Model.NAI_DIFFUSION_FURRY_3,
449
560
  Model.NAI_DIFFUSION_FURRY_3_INPAINTING,
450
561
  ]:
451
562
  prompts = [
452
- UcPrompt(category="heavy", name="heavy",
453
- text="{{worst quality}}, [displeasing], {unusual pupils}, guide lines, {{unfinished}}, {bad}, url, artist name, {{tall image}}, mosaic, {sketch page}, comic panel, impact (font), [dated], {logo}, ych, {what}, {where is your god now}, {distorted text}, repeated text, {floating head}, {1994}, {widescreen}, absolutely everyone, sequence, {compression artifacts}, hard translated, {cropped}, {commissioner name}, unknown text, high contrast"),
454
- UcPrompt(category="light", name="light",
455
- text="{worst quality}, guide lines, unfinished, bad, url, tall image, widescreen, compression artifacts, unknown text"),
456
- UcPrompt(category="none", name="none", text="lowres"),
563
+ UcPrompt(
564
+ category="heavy",
565
+ name="heavy",
566
+ text="{{worst quality}}, [displeasing], {unusual pupils}, guide lines, {{unfinished}}, {bad}, url, artist name, {{tall image}}, mosaic, {sketch page}, comic panel, impact (font), [dated], {logo}, ych, {what}, {where is your god now}, {distorted text}, repeated text, {floating head}, {1994}, {widescreen}, absolutely everyone, sequence, {compression artifacts}, hard translated, {cropped}, {commissioner name}, unknown text, high contrast"
567
+ ),
568
+ UcPrompt(
569
+ category="light",
570
+ name="light",
571
+ text="{worst quality}, guide lines, unfinished, bad, url, tall image, widescreen, compression artifacts, unknown text"
572
+ ),
573
+ UcPrompt(
574
+ category="none",
575
+ name="none",
576
+ text="lowres"
577
+ ),
457
578
  ]
458
579
  elif model in [
459
- Model.CUSTOM,
460
580
  Model.NAI_DIFFUSION_4_CURATED_PREVIEW,
581
+ Model.NAI_DIFFUSION_4_CURATED_INPAINTING,
582
+ ]:
583
+ prompts = [
584
+ UcPrompt(
585
+ category="heavy",
586
+ name="heavy",
587
+ text="blurry, lowres, error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, logo, dated, signature, multiple views, gigantic breasts"
588
+ ),
589
+ UcPrompt(
590
+ category="light",
591
+ name="light",
592
+ text="blurry, lowres, error, worst quality, bad quality, jpeg artifacts, very displeasing, logo, dated, signature"
593
+ ),
594
+ UcPrompt(
595
+ category="none",
596
+ name="none",
597
+ text=""
598
+ ),
599
+ ]
600
+ elif model in [
601
+ Model.CUSTOM,
602
+ Model.NAI_DIFFUSION_4_FULL,
603
+ Model.NAI_DIFFUSION_4_FULL_INPAINTING,
461
604
  ]:
462
605
  prompts = [
463
- UcPrompt(category="heavy", name="heavy",
464
- text="blurry, lowres, error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, logo, dated, signature, multiple views, gigantic breasts"),
465
- UcPrompt(category="light", name="light",
466
- text="blurry, lowres, error, worst quality, bad quality, jpeg artifacts, very displeasing, logo, dated, signature"),
467
- UcPrompt(category="none", name="none", text=""),
606
+ UcPrompt(
607
+ category="heavy",
608
+ name="heavy",
609
+ text="blurry, lowres, error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, multiple views, logo, too many watermarks, white blank page, blank page"
610
+ ),
611
+ UcPrompt(
612
+ category="light",
613
+ name="light",
614
+ text="blurry, lowres, error, worst quality, bad quality, jpeg artifacts, very displeasing, white blank page, blank page"
615
+ ),
616
+ UcPrompt(
617
+ category="none",
618
+ name="none",
619
+ text=""
620
+ ),
468
621
  ]
469
622
  return prompts
470
623
 
@@ -509,33 +509,13 @@ class GenerateImageInfer(ApiBaseModel):
509
509
  **NOTE: It is forbidden to write logic that does not belong to novelai.net here**
510
510
  :return: self
511
511
  """
512
- if self.action == Action.GENERATE:
513
- if self.parameters.image is not None:
514
- raise ValueError("You are using generate action, image is not required for non-generate mode.")
515
- if self.parameters.mask is not None:
516
- raise ValueError("You are using generate action, mask is not required for non-generate mode.")
517
-
518
- if self.action == Action.INFILL:
519
- if self.model not in INPAINTING_MODEL_LIST:
520
- raise ValueError(f"You must use {INPAINTING_MODEL_LIST}")
521
- if not self.parameters.mask:
522
- logger.warning("Mask maybe required for infill mode!")
523
-
524
- if self.action == Action.IMG2IMG:
525
- if self.parameters.extra_noise_seed is None:
526
- self.parameters.extra_noise_seed = self.parameters.seed
527
-
528
- if self.action == Action.IMG2IMG:
529
- if self.parameters.sm_dyn is True:
530
- logger.warning("sm_dyn be disabled when sm in Img2Img mode.")
531
- if self.parameters.sm is True:
532
- logger.warning("sm be disabled when sm_dyn in Img2Img mode.")
533
- self.parameters.sm = False
534
- self.parameters.sm_dyn = False
535
- if self.parameters.image is None:
536
- raise ValueError("image is must required for img2img mode.")
512
+ if self.parameters.characterPrompts:
513
+ self.parameters.use_coords = any([c.center != PositionMap.AUTO for c in self.parameters.characterPrompts])
514
+ # Mix Prompt Warning
515
+ if self.input.count('|') > 6:
516
+ logger.warning("Maximum prompt mixes exceeded. Extra will be ignored.")
537
517
 
538
- # Check Image
518
+ # Remove the image if the model does not support it
539
519
  if self.parameters.image is None:
540
520
  self.parameters.strength = None
541
521
  self.parameters.noise = None
@@ -553,31 +533,10 @@ class GenerateImageInfer(ApiBaseModel):
553
533
  self.parameters.sm_dyn = True
554
534
 
555
535
  if self.parameters.sm_dyn and (not self.parameters.sm):
556
- self.parameters.sm = True
557
-
558
- # AUTO SMEA SETTING
559
- """
560
- def sm_size_cast(model: Model):
561
- if model in [
562
- Model.NAI_DIFFUSION_V3,
563
- Model.NAI_DIFFUSION_V3_INPAINTING,
564
- Model.NAI_DIFFUSION_FURRY_V3,
565
- Model.NAI_DIFFUSION_FURRY_V3_INPAINTING,
566
- Model.CUSTOM
567
- ]:
568
- return 2166785
569
- return 1064961
570
- if self.parameters.autoSmea and (self.parameters.width * self.parameters.height < sm_size_cast(self.model)):
571
- self.parameters.autoSmea = False
572
- """
573
-
574
- if self.parameters.characterPrompts:
575
- self.parameters.use_coords = any([c.center != PositionMap.AUTO for c in self.parameters.characterPrompts])
576
-
577
- # Mix Prompt Warning
578
- if self.input.count('|') > 6:
579
- logger.warning("Maximum prompt mixes exceeded. Extra will be ignored.")
536
+ logger.warning("sm_dyn is disabled when sm is disabled.")
537
+ self.parameters.sm_dyn = False
580
538
 
539
+ # DDIM DON'T SUPPORT sm and sm_dyn
581
540
  if self.parameters.sampler in [
582
541
  Sampler.DDIM,
583
542
  Sampler.DDIM_V3
@@ -592,17 +551,33 @@ class GenerateImageInfer(ApiBaseModel):
592
551
 
593
552
  if self.parameters.uncond_scale == 0:
594
553
  self.parameters.uncond_scale = 0.00001
595
-
596
554
  if get_model_group(self.model) == ModelGroups.STABLE_DIFFUSION:
597
555
  self.parameters.uncond_scale = None
598
556
 
557
+ # Remove noise_schedule and cfg_rescale if not supported
599
558
  if not get_supported_params(self.model).noiseSchedule:
600
- self.parameters.noise_schedule = None
601
559
  self.parameters.cfg_rescale = None
560
+ self.parameters.noise_schedule = None
602
561
 
603
562
  if (self.model in INPAINTING_MODEL_LIST) and (self.parameters.sampler in [Sampler.DDIM, Sampler.DDIM_V3]):
604
563
  self.parameters.sampler = Sampler.K_EULER_ANCESTRAL
605
564
 
565
+ # AUTO SMEA SETTING
566
+ """
567
+ def sm_size_cast(model: Model):
568
+ if model in [
569
+ Model.NAI_DIFFUSION_V3,
570
+ Model.NAI_DIFFUSION_V3_INPAINTING,
571
+ Model.NAI_DIFFUSION_FURRY_V3,
572
+ Model.NAI_DIFFUSION_FURRY_V3_INPAINTING,
573
+ Model.CUSTOM
574
+ ]:
575
+ return 2166785
576
+ return 1064961
577
+ if self.parameters.autoSmea and (self.parameters.width * self.parameters.height < sm_size_cast(self.model)):
578
+ self.parameters.autoSmea = False
579
+ """
580
+
606
581
  if self.parameters.sampler in [
607
582
  Sampler.DDIM,
608
583
  Sampler.PLMS,
@@ -638,16 +613,46 @@ class GenerateImageInfer(ApiBaseModel):
638
613
  self.parameters.sm = None
639
614
  self.parameters.sm_dyn = None
640
615
 
616
+ if not get_supported_params(self.model).dynamicThresholding:
617
+ self.parameters.dynamic_thresholding = False
618
+
619
+ if self.model == Model.CUSTOM and self.action == Action.INFILL:
620
+ self.endpoint = "http://custom-exposed-full-inpaint-anime-v4-staging.ai.svc.cluster.local/"
621
+
641
622
  # == Noise Schedule ==
642
623
  if self.parameters.noise_schedule is None:
643
624
  self.parameters.noise_schedule = get_default_noise_schedule(self.parameters.sampler)
644
- supported_noise_schedule = get_supported_noise_schedule(self.parameters.sampler)
625
+ supported_noise_schedule = get_supported_noise_schedule(sample_type=self.parameters.sampler, model=self.model)
645
626
  if supported_noise_schedule:
646
627
  if self.parameters.noise_schedule not in supported_noise_schedule:
647
628
  raise ValueError(f"Invalid noise_schedule, must be one of {supported_noise_schedule}")
648
629
  else:
649
630
  logger.warning(f"Inactive sampler {self.parameters.sampler} does not support noise_schedule.")
650
631
 
632
+ # == Action ==
633
+ if self.action == Action.GENERATE:
634
+ if self.parameters.image is not None:
635
+ raise ValueError("You are using generate action, image is not required for non-generate mode.")
636
+ if self.parameters.mask is not None:
637
+ raise ValueError("You are using generate action, mask is not required for non-generate mode.")
638
+ if self.action == Action.INFILL:
639
+ if self.model not in INPAINTING_MODEL_LIST:
640
+ raise ValueError(f"You must use {INPAINTING_MODEL_LIST}")
641
+ if not self.parameters.mask:
642
+ logger.warning("Mask maybe required for infill mode!")
643
+ if self.action == Action.IMG2IMG:
644
+ if self.parameters.extra_noise_seed is None:
645
+ self.parameters.extra_noise_seed = self.parameters.seed
646
+ if self.action == Action.IMG2IMG:
647
+ if self.parameters.sm_dyn is True:
648
+ logger.warning("sm_dyn be disabled when sm in Img2Img mode.")
649
+ if self.parameters.sm is True:
650
+ logger.warning("sm be disabled when sm_dyn in Img2Img mode.")
651
+ self.parameters.sm = False
652
+ self.parameters.sm_dyn = False
653
+ if self.parameters.image is None:
654
+ raise ValueError("image is must required for img2img mode.")
655
+
651
656
  return self
652
657
 
653
658
  @property
@@ -12,7 +12,7 @@ from nacl.encoding import Base64Encoder
12
12
  from nacl.signing import VerifyKey
13
13
  from pydantic import BaseModel, ConfigDict
14
14
 
15
- from novelai_python.sdk.ai._enum import PROMOTION, Model
15
+ from novelai_python.sdk.ai._enum import PROMOTION, Model, find_model_by_hashcode
16
16
  from .bch_utils import fec_decode
17
17
  from .lsb_extractor import ImageLsbDataExtractor
18
18
  from .lsb_injector import inject_data
@@ -125,7 +125,7 @@ class ImageMetadata(BaseModel):
125
125
  Get the model used to generate the image from the Model code
126
126
  :return: Model or None
127
127
  """
128
- return PROMOTION.get(self.Source, None)
128
+ return find_model_by_hashcode(self.Source)
129
129
 
130
130
  @staticmethod
131
131
  def reset_alpha(image: Image.Image) -> BytesIO:
File without changes
File without changes
File without changes