stability_sdk 0.2.11 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 431d7a70dc0a5a538abdbe9a486bf5c632d1e6a8e7e58dd7fedf1fa89b15722b
4
- data.tar.gz: a6d5c05cf4915e7c91ceeb92864b2cc84f852ec40a61ce174ba57b3a97ec0df9
3
+ metadata.gz: 3e707d41b381676dfbc958975bae028b82a52a7828529c52db7809db125791e9
4
+ data.tar.gz: 9e7aafbd1c0e5638ad2bc860312e55a0b2973ec3c8423fa050730cfa15887efa
5
5
  SHA512:
6
- metadata.gz: 7c5ba5862fd6446e243cdf54760fe596a4298e2d2860183df4cef847cc75d4414e9ceb21e8bd927e71e0fbacca9ce742628107197ca1e7c380abbbabff1e7cdc
7
- data.tar.gz: 69b3cef394cbd5bd784bfd8953b1bd8721e4921e96f3a7bda79c0de3a733692853005008e1946cad75b24889df5dc1c8f9479238baac488a37a64ef49dbe39b7
6
+ metadata.gz: 37cb8a18a1accb3cf30f6dc780781f71dfe75ad648713a2c335d1b2be41f7546c0450d88ec0ae833354db24a3d3659fe0ac8163d1f3a1a076f08e8e344282c9c
7
+ data.tar.gz: aa66ce05d53d3d5bd6aa661f752a5d71f61c9835804d69f38834e07bc4e5259d971816eb4d4061264cfadc9a825a425b0469c794369eb48c1080cdbf1d1342d3
data/README.md CHANGED
@@ -61,9 +61,25 @@ Options:
61
61
  -m, --mask_image=VAL path to mask image
62
62
  --start_schedule=VAL start schedule for init image (must be greater than 0, 1 is full strength text prompt, no trace of image). default 1.0
63
63
  --end_schedule=VAL end schedule for init image. default 0.01
64
+ --guidance_preset=VAL Guidance preset to use. See generation.GuidancePreset for supported values. default `GUIDANCE_PRESET_NONE`
65
+ --guidance_cuts=VAL Number of cuts to use for guidance. default 0
66
+ --guidance_strength=VAL Strength of the guidance. We recommend values in range [0.0,1.0]. A good default is 0.25. default nil
67
+ --guidance_prompt=VAL Prompt to use for guidance, defaults to `YOUR_PROMPT_TEXT` argument (above) if not specified.
68
+ --guidance_models=VAL Models to use for guidance. default nil
64
69
  -v, --verbose
65
70
  ```
66
71
 
72
+ #### CLIP guidance
73
+
74
+ By specifying `--guidance_preset` and other `--guidance_*` options, you can use CLIP guidance, which is enabled by default on DreamStudio's web interface.
75
+ See also [this notebook](https://github.com/Stability-AI/stability-sdk/blob/c04381f960008f37c7392467cfaabfdf8f763e6a/nbs/demo_colab.ipynb) for more details.
76
+
77
+ ```sh
78
+ # example
79
+ # [note] --steps=35 is recommended. which is also the default value of the web interface
80
+ STABILITY_SDK_API_KEY=xxx stability-client --guidance_preset=GUIDANCE_PRESET_FAST_BLUE --guidance_strength=0.25 --steps=35 --sampler=k_dpm_2_ancestral "A dream of a distant galaxy, by Caspar David Friedrich, matte painting trending on artstation HQ"
81
+ ```
82
+
67
83
  ### SDK usage
68
84
 
69
85
  This sample code saves a generated image as `result.png`.
@@ -91,23 +107,29 @@ client.generate(prompt, options) do |answer|
91
107
  end
92
108
  ```
93
109
 
94
- ### [Unstable] Dashboard API
95
-
96
- **This feature is in a very early stage of development.**
110
+ ### Dashboard API
97
111
 
98
112
  Dashboard API is a way to interact with DreamStudio Web UIs, such as getting user info, payment info, etc.
99
113
 
100
- Currently, there is no canonical way to get the API key for the Dashboard API. You can retrieve the key by logging in to the [DreamStudio Web page](https://beta.dreamstudio.ai/dream) and inspect request the authorization header with Chrome Developer Tool. Please be aware that how to refresh the key or an expiration period is unknown. See also https://github.com/Stability-AI/stability-sdk/issues/23
114
+ Currently, the API key is only allowed as read-only. And this client supports only GetMe and GetOrganization actions. See also https://github.com/Stability-AI/stability-sdk/issues/23
101
115
 
102
116
  ```sh
103
117
  # get user info
104
- STABILITY_SDK_DASHBOARD_API_KEY=YOUR_API_KEY stability-dashboard-client-unstable get_me
118
+ STABILITY_SDK_DASHBOARD_API_KEY=YOUR_API_KEY stability-dashboard-client get_me
105
119
 
106
120
  # get organization info
107
- STABILITY_SDK_DASHBOARD_API_KEY=YOUR_API_KEY stability-dashboard-client-unstable get_organization
121
+ STABILITY_SDK_DASHBOARD_API_KEY=YOUR_API_KEY stability-dashboard-client get_organization
108
122
 
109
123
  # i.e, get remaining balance
110
- STABILITY_SDK_DASHBOARD_API_KEY=YOUR_API_KEY stability-dashboard-client-unstable get_organization | jq .paymentInfo.balance
124
+ STABILITY_SDK_DASHBOARD_API_KEY=YOUR_API_KEY stability-dashboard-client get_organization | jq .paymentInfo.balance
125
+ ```
126
+
127
+ ```ruby
128
+ require "stability_sdk"
129
+
130
+ client = StabilitySDK::DashboardClient.new(api_key: "your api key")
131
+ res = client.get_organization
132
+ p res.payment_info.balance # prints a remaining balance
111
133
  ```
112
134
 
113
135
  ## Development
@@ -116,6 +138,32 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
116
138
 
117
139
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
118
140
 
141
+ ### update submodule to try a new feature on Stability-AI/api-interfaces
142
+
143
+ - update submodule
144
+
145
+ ```sh
146
+ git submodule update --init # if you haven't fetched the content of the submodule yet
147
+ cd api-interfaces
148
+
149
+ # checkout some branch/commit you need
150
+ git fetch
151
+ git reset --hard origin/some_branch
152
+
153
+ cd ..
154
+ ```
155
+
156
+ - build
157
+
158
+ ```sh
159
+ bundle exec rake protoc
160
+
161
+ git diff
162
+ # now you may be able to confirm that the diff is created in lib/generation_pb.rb
163
+ ```
164
+
165
+ - modify the `lib/stability_sdk/client.rb` to try some new features
166
+
119
167
  ## Contributing
120
168
 
121
169
  Bug reports and pull requests are welcome on GitHub at https://github.com/cou929/stability-sdk-ruby.
data/exe/stability-client CHANGED
@@ -18,20 +18,25 @@ opt.banner = "Usage: stability-client [options] YOUR_PROMPT_TEXT"
18
18
  opt.separator ""
19
19
  opt.separator "Options:"
20
20
  opt.on("--api_key=VAL", "api key of DreamStudio account. You can also specify by a STABILITY_SDK_API_KEY environment variable") {|v| options[:api_key] = v }
21
- opt.on("-H", "--height=VAL", "height of image in pixel. default 512") {|v| options[:height] = v }
22
- opt.on("-W", "--width=VAL", "width of image in pixel. default 512") {|v| options[:width] = v }
23
- opt.on("-C", "--cfg_scale=VAL", "CFG scale factor. default 7.0") {|v| options[:cfg_scale] = v }
24
- opt.on("-A", "--sampler=VAL", "ddim, plms, k_euler, k_euler_ancestral, k_heun, k_dpm_2, k_dpm_2_ancestral, k_lms. default k_lms") {|v| options[:sampler] = v }
25
- opt.on("-s", "--steps=VAL", "number of steps. default 50") {|v| options[:steps] = v }
26
- opt.on("-S", "--seed=VAL", "random seed to use in integer") {|v| options[:seed] = v }
27
- opt.on("-p", "--prefix=VAL", "output prefixes for artifacts. default `generation`") {|v| options[:prefix] = v }
21
+ opt.on("-H", "--height=VAL", Integer, "height of image in pixel. default 512") {|v| options[:height] = v }
22
+ opt.on("-W", "--width=VAL", Integer, "width of image in pixel. default 512") {|v| options[:width] = v }
23
+ opt.on("-C", "--cfg_scale=VAL", Float, "CFG scale factor. default 7.0") {|v| options[:cfg_scale] = v }
24
+ opt.on("-A", "--sampler=VAL", String, "ddim, plms, k_euler, k_euler_ancestral, k_heun, k_dpm_2, k_dpm_2_ancestral, k_lms. default k_lms") {|v| options[:sampler] = v }
25
+ opt.on("-s", "--steps=VAL", Integer, "number of steps. default 50") {|v| options[:steps] = v }
26
+ opt.on("-S", "--seed=VAL", Integer, "random seed to use in integer") {|v| options[:seed] = v }
27
+ opt.on("-p", "--prefix=VAL", String, "output prefixes for artifacts. default `generation`") {|v| options[:prefix] = v }
28
28
  opt.on("--no-store", "do not write out artifacts") {|v| options[:no_store] = v }
29
- opt.on("-n", "--num_samples=VAL", "number of samples to generate") {|v| options[:num_samples] = v }
30
- opt.on("-e", "--engine=VAL", "engine to use for inference. default `stable-diffusion-v1`") {|v| options[:engine_id] = v }
31
- opt.on("-i", "--init_image=VAL", "path to init image") {|v| options[:init_image] = v }
32
- opt.on("-m", "--mask_image=VAL", "path to mask image") {|v| options[:mask_image] = v }
33
- opt.on("--start_schedule=VAL", "start schedule for init image (must be greater than 0, 1 is full strength text prompt, no trace of image). default 1.0") {|v| options[:start_schedule] = v }
34
- opt.on("--end_schedule=VAL", "end schedule for init image. default 0.01") {|v| options[:end_schedule] = v }
29
+ opt.on("-n", "--num_samples=VAL", Integer, "number of samples to generate. default 1") {|v| options[:num_samples] = v }
30
+ opt.on("-e", "--engine=VAL", String, "engine to use for inference. default `stable-diffusion-v1-5`") {|v| options[:engine_id] = v }
31
+ opt.on("-i", "--init_image=VAL", String, "path to init image") {|v| options[:init_image] = v }
32
+ opt.on("-m", "--mask_image=VAL", String, "path to mask image") {|v| options[:mask_image] = v }
33
+ opt.on("--start_schedule=VAL", Float, "start schedule for init image (must be greater than 0, 1 is full strength text prompt, no trace of image). default 1.0") {|v| options[:start_schedule] = v }
34
+ opt.on("--end_schedule=VAL", Float, "end schedule for init image. default 0.01") {|v| options[:end_schedule] = v }
35
+ opt.on("--guidance_preset=VAL", String,"Guidance preset to use. See generation.GuidancePreset for supported values. default `GUIDANCE_PRESET_NONE`") {|v| options[:guidance_preset] = v }
36
+ opt.on("--guidance_cuts=VAL", Integer, "Number of cuts to use for guidance. default 0") {|v| options[:guidance_cuts] = v }
37
+ opt.on("--guidance_strength=VAL", Float, "Strength of the guidance. We recommend values in range [0.0,1.0]. A good default is 0.25. default nil") {|v| options[:guidance_strength] = v }
38
+ opt.on("--guidance_prompt=VAL", String, "Prompt to use for guidance, defaults to `YOUR_PROMPT_TEXT` argument (above) if not specified.") {|v| options[:guidance_prompt] = v }
39
+ opt.on("--guidance_models=VAL", Array, "Models to use for guidance. default nil") {|v| options[:guidance_models] = v }
35
40
  opt.on("-v", "--verbose") { logger.level = Logger::DEBUG }
36
41
  opt.parse!(ARGV)
37
42
 
@@ -48,7 +53,7 @@ if options.has_key?(:init_image)
48
53
  raise StabilitySDK::InvalidParameter, "width and height of init_image must be a multiple of 64" if size[0] % 64 != 0 || size[1] % 64 != 0
49
54
  end
50
55
 
51
- client = StabilitySDK::Client.new(api_key: options[:api_key])
56
+ client = StabilitySDK::Client.new(api_key: options[:api_key], logger: logger)
52
57
 
53
58
  client.generate(prompt, options) do |answer|
54
59
  StabilitySDK::CLI.save_answer(answer, options, logger)
@@ -33,7 +33,7 @@ class CLI < Thor
33
33
  api_key = ENV["STABILITY_SDK_DASHBOARD_API_KEY"] if ENV["STABILITY_SDK_DASHBOARD_API_KEY"]
34
34
  raise StabilitySDK::InsufficientParameter, "api key is required" if api_key.nil?
35
35
 
36
- return StabilitySDK::Unstable::DashboardClient.new(api_key: api_key)
36
+ return StabilitySDK::DashboardClient.new(api_key: api_key)
37
37
  end
38
38
  end
39
39
 
@@ -23,10 +23,15 @@ module StabilitySDK
23
23
  logger.warn "not implemented for ArtifactType #{artifact.type}"
24
24
  end
25
25
 
26
+ if artifact.finish_reason == :FILTER
27
+ logger.debug "the generated image is filtered"
28
+ end
29
+
26
30
  next if filename == "" || contents == ""
27
31
 
28
32
  File.open(filename, "wb") do |f|
29
33
  f.write(contents)
34
+ logger.debug "wrote #{artifact.type} to #{filename}"
30
35
  end
31
36
  end
32
37
  end
@@ -1,5 +1,6 @@
1
1
  require "grpc"
2
2
  require "generation_services_pb"
3
+ require "logger"
3
4
 
4
5
  module StabilitySDK
5
6
  class Client
@@ -36,29 +37,37 @@ module StabilitySDK
36
37
  stub_params[kw] = options[kw] if options.has_key?(kw)
37
38
  end
38
39
 
40
+ if options.has_key?(:logger)
41
+ @logger = options[:logger]
42
+ else
43
+ logger = Logger.new(STDOUT)
44
+ logger.level = Logger::WARN
45
+ @logger = logger
46
+ end
47
+
39
48
  @stub = Gooseai::GenerationService::Stub.new(host, creds, **stub_params)
40
49
  end
41
50
 
42
51
  def generate(prompt, options, &block)
43
- width = options.has_key?(:width) ? options[:width].to_i : DEFAULT_IMAGE_WIDTH
44
- height = options.has_key?(:height) ? options[:height].to_i : DEFAULT_IMAGE_HEIGHT
52
+ width = options.has_key?(:width) ? options[:width] : DEFAULT_IMAGE_WIDTH
53
+ height = options.has_key?(:height) ? options[:height] : DEFAULT_IMAGE_HEIGHT
45
54
 
46
55
  if width % 64 != 0 || height % 64 != 0
47
56
  raise InvalidParameter, "width and height must be a multiple of 64"
48
57
  end
49
58
 
50
- samples = options.has_key?(:num_samples) ? options[:num_samples].to_i : DEFAULT_SAMPLE_SIZE
51
- steps = options.has_key?(:steps) ? options[:steps].to_i : DEFAULT_STEPS
52
- seed = options.has_key?(:seed) ? [options[:seed].to_i] : [rand(4294967295)]
59
+ samples = options.has_key?(:num_samples) ? options[:num_samples] : DEFAULT_SAMPLE_SIZE
60
+ steps = options.has_key?(:steps) ? options[:steps] : DEFAULT_STEPS
61
+ seed = options.has_key?(:seed) ? [options[:seed]] : [rand(4294967295)]
53
62
  transform = Gooseai::TransformType.new(
54
- diffusion: options.has_key?(:sampler) ? SAMPLER_ALGORITHMS[options[:sampler]] : DEFAULT_SAMPLER_ALGORITHM,
63
+ diffusion: options.has_key?(:sampler) ? SAMPLER_ALGORITHMS[options[:sampler].to_sym] : DEFAULT_SAMPLER_ALGORITHM,
55
64
  )
56
- parameters = [Gooseai::StepParameter.new(
65
+ step_parameter = Gooseai::StepParameter.new(
57
66
  scaled_step: 0,
58
67
  sampler: Gooseai::SamplerParameters.new(
59
- cfg_scale: options.has_key?(:cfg_scale) ? options[:cfg_scale].to_f : DEFAULT_CFG_SCALE,
68
+ cfg_scale: options.has_key?(:cfg_scale) ? options[:cfg_scale] : DEFAULT_CFG_SCALE,
60
69
  ),
61
- )]
70
+ )
62
71
 
63
72
  prompt_param = []
64
73
  if prompt != ""
@@ -66,21 +75,65 @@ module StabilitySDK
66
75
  end
67
76
  if options.has_key?(:init_image)
68
77
  prompt_param << init_image_to_prompt(options[:init_image])
69
- parameters = [Gooseai::StepParameter.new(
70
- scaled_step: 0,
71
- sampler: Gooseai::SamplerParameters.new(
72
- cfg_scale: options.has_key?(:cfg_scale) ? options[:cfg_scale].to_f : DEFAULT_CFG_SCALE,
73
- ),
74
- schedule: Gooseai::ScheduleParameters.new(
75
- start: options.has_key?(:start_schedule) ? options[:start_schedule].to_f : DEFAULT_START_SCHEDULE,
76
- end: options.has_key?(:end_schedule) ? options[:end_schedule].to_f : DEFAULT_END_SCHEDULE,
77
- ),
78
- )]
78
+ step_parameter.scaled_step = 0
79
+ step_parameter.sampler = Gooseai::SamplerParameters.new(
80
+ cfg_scale: options.has_key?(:cfg_scale) ? options[:cfg_scale] : DEFAULT_CFG_SCALE,
81
+ )
82
+ step_parameter.schedule = Gooseai::ScheduleParameters.new(
83
+ start: options.has_key?(:start_schedule) ? options[:start_schedule] : DEFAULT_START_SCHEDULE,
84
+ end: options.has_key?(:end_schedule) ? options[:end_schedule] : DEFAULT_END_SCHEDULE,
85
+ )
79
86
  end
80
87
  if options.has_key?(:mask_image)
81
88
  prompt_param << mask_image_to_prompt(options[:mask_image])
82
89
  end
83
90
 
91
+ # CLIP guidance
92
+ if options.has_key?(:guidance_preset) && options[:guidance_preset] != "GUIDANCE_PRESET_NONE"
93
+ step_parameter.sampler = nil
94
+
95
+ guidance_prompt =
96
+ if options.has_key?(:guidance_prompt)
97
+ Gooseai::Prompt.new(text: options[:guidance_prompt])
98
+ else
99
+ Gooseai::Prompt.new(text: prompt)
100
+ end
101
+
102
+ guidance_strength = nil
103
+ if options.has_key?(:guidance_strength) && options[:guidance_strength] != 0
104
+ guidance_strength = options[:guidance_strength]
105
+ end
106
+
107
+ models = nil
108
+ if options.has_key?(:guidance_models)
109
+ models = options[:guidance_models].map { |m| Gooseai::Model.new(alias: m) }
110
+ end
111
+
112
+ cutouts = nil
113
+ if options.has_key?(:guidance_cuts)
114
+ cutouts = Gooseai::CutoutParameters.new(count: options[:guidance_cuts])
115
+ end
116
+
117
+ step_parameter.guidance = Gooseai::GuidanceParameters.new(
118
+ guidance_preset: Gooseai::GuidancePreset.const_get(options[:guidance_preset].to_sym),
119
+ instances: [
120
+ Gooseai::GuidanceInstanceParameters.new(
121
+ guidance_strength: guidance_strength,
122
+ models: models,
123
+ cutouts: cutouts,
124
+ prompt: guidance_prompt,
125
+ ),
126
+ ],
127
+ )
128
+
129
+ if transform.diffusion != Gooseai::DiffusionSampler::SAMPLER_K_DPM_2_ANCESTRAL && transform.diffusion != Gooseai::DiffusionSampler::SAMPLER_K_EULER_ANCESTRAL
130
+ transform = Gooseai::TransformType.new(
131
+ diffusion: Gooseai::DiffusionSampler::SAMPLER_K_DPM_2_ANCESTRAL
132
+ )
133
+ @logger.warn "CLIP guidance is only supported with ancestral samplers. So override it with SAMPLER_K_DPM_2_ANCESTRAL."
134
+ end
135
+ end
136
+
84
137
  image_param = Gooseai::ImageParameters.new(
85
138
  width: width,
86
139
  height: height,
@@ -88,7 +141,7 @@ module StabilitySDK
88
141
  steps: steps,
89
142
  seed: seed,
90
143
  transform: transform,
91
- parameters: parameters,
144
+ parameters: [step_parameter],
92
145
  )
93
146
 
94
147
  req = Gooseai::Request.new(
@@ -97,8 +150,20 @@ module StabilitySDK
97
150
  image: image_param
98
151
  )
99
152
 
153
+ @logger.debug "sending request."
154
+ start = Time.now
100
155
  @stub.generate(req).each do |answer|
156
+ duration = Time.now - start
157
+ if answer.artifacts.size > 0
158
+ artifact_types = answer.artifacts.map { |a| a.type }
159
+ @logger.debug "got #{answer.answer_id} with #{artifact_types} in #{duration.round(2)}s"
160
+ else
161
+ @logger.debug "got keepalive #{answer.answer_id} in #{duration.round(2)}s"
162
+ end
163
+
101
164
  block.call(answer)
165
+
166
+ start = Time.now
102
167
  end
103
168
  end
104
169
 
@@ -1,7 +1,7 @@
1
1
  require "grpc"
2
2
  require "dashboard_services_pb"
3
3
 
4
- module StabilitySDK::Unstable
4
+ module StabilitySDK
5
5
  class DashboardClient
6
6
  DEFAULT_API_HOST = "grpc.stability.ai:443"
7
7
 
@@ -1,3 +1,3 @@
1
1
  module StabilitySDK
2
- VERSION = "0.2.11"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/stability_sdk.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "stability_sdk/version"
2
2
  require "stability_sdk/client"
3
3
  require "stability_sdk/cli"
4
- require "stability_sdk/unstable/dashboard_client"
4
+ require "stability_sdk/dashboard_client"
5
5
 
6
6
  module StabilitySDK
7
7
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stability_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.11
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kosei Moriyama
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-28 00:00:00.000000000 Z
11
+ date: 2022-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc
@@ -92,7 +92,7 @@ email:
92
92
  - cou929@gmail.com
93
93
  executables:
94
94
  - stability-client
95
- - stability-dashboard-client-unstable
95
+ - stability-dashboard-client
96
96
  extensions: []
97
97
  extra_rdoc_files: []
98
98
  files:
@@ -106,7 +106,7 @@ files:
106
106
  - bin/console
107
107
  - bin/setup
108
108
  - exe/stability-client
109
- - exe/stability-dashboard-client-unstable
109
+ - exe/stability-dashboard-client
110
110
  - lib/dashboard_pb.rb
111
111
  - lib/dashboard_services_pb.rb
112
112
  - lib/generation_pb.rb
@@ -114,7 +114,7 @@ files:
114
114
  - lib/stability_sdk.rb
115
115
  - lib/stability_sdk/cli.rb
116
116
  - lib/stability_sdk/client.rb
117
- - lib/stability_sdk/unstable/dashboard_client.rb
117
+ - lib/stability_sdk/dashboard_client.rb
118
118
  - lib/stability_sdk/version.rb
119
119
  - stability_sdk.gemspec
120
120
  homepage: https://github.com/cou929/stability-sdk-ruby