-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Stable diffusion automatic API Server support (#43)
* add sd automatic111111 as an option * add --sd-api option for using external api server * automatic111111 support. * choose model for sd automatic11111 * readme updated for stable diffusion * add ./bin/ with startup scripts for API servers * add mimic3 server startup script * add back image scaling for automatic1111111 --------- Co-authored-by: Chris Kennedy <[email protected]>
- Loading branch information
1 parent
7da437b
commit 2326638
Showing
12 changed files
with
265 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,3 +83,4 @@ urlencoding = "2.1.3" | |
clap_builder = "4.5.2" | ||
safetensors = "0.4.2" | ||
ctrlc = "3.4.4" | ||
base64 = "0.22.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/bin/bash | ||
# | ||
#MODEL=/Volumes/BrahmaSSD/LLM/models/GGUF/dolphin-2.7-mixtral-8x7b.Q5_K_M.gguf | ||
MODEL=/Volumes/BrahmaSSD/LLM/models/GGUF/dolphin-2.7-mixtral-8x7b.Q8_0.gguf | ||
|
||
server \ | ||
-m $MODEL \ | ||
-c 0 \ | ||
-np 2 \ | ||
--port 8080 \ | ||
-ngl 60 \ | ||
-t 24 \ | ||
--host 0.0.0.0 $@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import subprocess | ||
from hashlib import md5 | ||
|
||
# Configuration | ||
music_dir = "/Volumes/BrahmaSSD/music/AiGen" | ||
output_file = "/tmp/combined_playlist.wav" | ||
playlist_file = "/tmp/ffmpeg_playlist.txt" | ||
checksum_file = "/tmp/playlist_checksum.txt" | ||
|
||
def get_files_sorted_by_mtime(directory, extension=".wav"): | ||
files = [] | ||
for root, dirs, filenames in os.walk(directory): | ||
for filename in filenames: | ||
if filename.endswith(extension): | ||
full_path = os.path.join(root, filename) | ||
files.append(full_path) | ||
return sorted(files, key=os.path.getmtime) | ||
|
||
def generate_playlist(files, playlist_path): | ||
with open(playlist_path, 'w') as playlist: | ||
for file in files: | ||
playlist.write(f"file '{file}'\n") | ||
|
||
def calculate_checksum(files): | ||
hash_md5 = md5() | ||
for file in files: | ||
with open(file, "rb") as f: | ||
for chunk in iter(lambda: f.read(4096), b""): | ||
hash_md5.update(chunk) | ||
return hash_md5.hexdigest() | ||
|
||
def read_previous_checksum(checksum_path): | ||
try: | ||
with open(checksum_path, 'r') as file: | ||
return file.read().strip() | ||
except FileNotFoundError: | ||
return '' | ||
|
||
def write_new_checksum(checksum, checksum_path): | ||
with open(checksum_path, 'w') as file: | ||
file.write(checksum) | ||
|
||
def concatenate_files(playlist_path, output_path): | ||
cmd = ['ffmpeg', '-y', '-hide_banner', '-f', 'concat', '-safe', '0', '-i', playlist_path, '-c', 'copy', output_path] | ||
print("Running command:", ' '.join(cmd)) | ||
subprocess.run(cmd, check=True) | ||
|
||
def play_audio(file_path): | ||
subprocess.run(['mpv', '--volume=50', file_path], check=True) | ||
|
||
while True: | ||
files = get_files_sorted_by_mtime(music_dir) | ||
if not files: | ||
print("No .wav files found in the directory.") | ||
else: | ||
current_checksum = calculate_checksum(files) | ||
previous_checksum = read_previous_checksum(checksum_file) | ||
|
||
if current_checksum != previous_checksum or not os.path.exists(output_file): | ||
print("Changes detected or output file missing, regenerating...") | ||
generate_playlist(files, playlist_file) | ||
concatenate_files(playlist_file, output_file) | ||
write_new_checksum(current_checksum, checksum_file) | ||
else: | ||
print("No changes detected. Using existing combined audio file.") | ||
|
||
print("Playing combined playlist...") | ||
play_audio(output_file) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
# | ||
mimic3-server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
# | ||
# https://github.com/AUTOMATIC1111/stable-diffusion-webui.git | ||
# | ||
./webui.sh --api --api-log --nowebui --port 7860 --skip-torch-cuda-test --no-half --use-cpu all | ||
#./webui.sh --api --api-log --port 7860 --skip-torch-cuda-test --no-half --use-cpu all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use crate::scale_image; | ||
use crate::stable_diffusion::SDConfig; | ||
use crate::stable_diffusion::StableDiffusionVersion; | ||
use anyhow::Result; | ||
use base64::engine::general_purpose; | ||
use base64::Engine; | ||
use image::ImageBuffer; | ||
use image::Rgb; | ||
use reqwest::Client; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
pub async fn sd_auto( | ||
config: SDConfig, | ||
) -> Result<Vec<ImageBuffer<Rgb<u8>, Vec<u8>>>, anyhow::Error> { | ||
let client = Client::new(); | ||
|
||
let model = match config.sd_version { | ||
StableDiffusionVersion::V1_5 => "v1-5-pruned-emaonly.ckpt", | ||
StableDiffusionVersion::V2_1 => "v2-1_768-ema-pruned.ckpt", | ||
StableDiffusionVersion::Xl => "stabilityai/stable-diffusion-xl-1024-1.0.ckpt", | ||
StableDiffusionVersion::Turbo => "madebyollin/turbo-diffusion.ckpt", | ||
}; | ||
|
||
let payload = AutomaticPayload { | ||
prompt: config.prompt, | ||
negative_prompt: config.uncond_prompt, | ||
steps: config.n_steps.unwrap_or(20), | ||
width: config.width.unwrap_or(512), | ||
height: config.height.unwrap_or(512), | ||
cfg_scale: config.guidance_scale.unwrap_or(7.5), | ||
sampler_index: "Euler".to_string(), | ||
seed: config.seed.unwrap_or_else(rand::random) as u64, | ||
n_iter: config.num_samples, | ||
batch_size: 1, | ||
override_settings: OverrideSettings { | ||
sd_model_checkpoint: model.to_string(), | ||
}, | ||
}; | ||
|
||
let response = client | ||
.post("http://127.0.0.1:7860/sdapi/v1/txt2img") | ||
.json(&payload) | ||
.send() | ||
.await?; | ||
|
||
let response_json: serde_json::Value = response.json().await?; | ||
let image_data = response_json["images"].as_array().unwrap(); | ||
|
||
let mut images = Vec::new(); | ||
for image_base64 in image_data { | ||
let image_bytes = general_purpose::STANDARD | ||
.decode(image_base64.as_str().unwrap()) | ||
.unwrap(); | ||
let image = image::load_from_memory(&image_bytes)?; | ||
let image_rgb8 = image.to_rgb8(); | ||
images.push(image_rgb8); | ||
} | ||
|
||
let scaled_images: Vec<ImageBuffer<Rgb<u8>, Vec<u8>>> = images | ||
.into_iter() | ||
.map(|image| { | ||
scale_image( | ||
image, | ||
config.scaled_width, | ||
config.scaled_height, | ||
config.image_position.clone(), | ||
) | ||
}) | ||
.collect(); | ||
|
||
Ok(scaled_images) | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
struct OverrideSettings { | ||
sd_model_checkpoint: String, | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
struct AutomaticPayload { | ||
prompt: String, | ||
negative_prompt: String, | ||
steps: usize, | ||
width: usize, | ||
height: usize, | ||
cfg_scale: f64, | ||
sampler_index: String, | ||
seed: u64, | ||
n_iter: usize, | ||
batch_size: usize, | ||
override_settings: OverrideSettings, | ||
} |
Oops, something went wrong.