stability_sdk 0.2.11 → 0.2.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +42 -0
- data/exe/stability-client +19 -14
- data/lib/stability_sdk/cli.rb +5 -0
- data/lib/stability_sdk/client.rb +85 -20
- data/lib/stability_sdk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5aac33cb8d504aab26b515dc2fa6bd9d76c70829a0aa706eabc6be39043b143
|
4
|
+
data.tar.gz: ca6a3cd1cd24763a9f9427132a4e8fde4c688d9bc9d3409ef921139fa62fa232
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95b76f6caf8e5a32af792cc0d284f81b76c7e38c682b24a5fc91204b3373096a47a98ab1ee6f0e32cbbd2039ad6b57c920c262661cda221c54eac529bd54e51a
|
7
|
+
data.tar.gz: f196c8b879b36e69c84d40c2528fd9fbf7f07e1ae6eec9c4a996a66a8a73841ea50d73d8ca941b7813ca9d5fbada94140143619bdb841de4ce9f71316af1303e
|
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`.
|
@@ -116,6 +132,32 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
116
132
|
|
117
133
|
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
134
|
|
135
|
+
### update submodule to try a new feature on Stability-AI/api-interfaces
|
136
|
+
|
137
|
+
- update submodule
|
138
|
+
|
139
|
+
```sh
|
140
|
+
git submodule update --init # if you haven't fetched the content of the submodule yet
|
141
|
+
cd api-interfaces
|
142
|
+
|
143
|
+
# checkout some branch/commit you need
|
144
|
+
git fetch
|
145
|
+
git reset --hard origin/some_branch
|
146
|
+
|
147
|
+
cd ..
|
148
|
+
```
|
149
|
+
|
150
|
+
- build
|
151
|
+
|
152
|
+
```sh
|
153
|
+
bundle exec rake protoc
|
154
|
+
|
155
|
+
git diff
|
156
|
+
# now you may be able to confirm that the diff is created in lib/generation_pb.rb
|
157
|
+
```
|
158
|
+
|
159
|
+
- modify the `lib/stability_sdk/client.rb` to try some new features
|
160
|
+
|
119
161
|
## Contributing
|
120
162
|
|
121
163
|
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)
|
data/lib/stability_sdk/cli.rb
CHANGED
@@ -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
|
data/lib/stability_sdk/client.rb
CHANGED
@@ -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]
|
44
|
-
height = options.has_key?(:height) ? options[: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]
|
51
|
-
steps = options.has_key?(:steps) ? options[:steps]
|
52
|
-
seed = options.has_key?(:seed) ? [options[:seed]
|
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
|
-
|
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]
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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:
|
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
|
|
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.
|
4
|
+
version: 0.2.12
|
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-
|
11
|
+
date: 2022-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|