实现一个基于 Tauri 的Stable Diffusion UI,软软 AI 中集成Stable Diffusion

666 阅读2分钟

实现一个基于 Tauri 的Stable Diffusion UI,软软 AI 中集成Stable Diffusion

(功能部分实现,待完善)

需求

  • 在软软 AI 中实现可以以任务的方式远程执行Stable Diffusion的任务。
  • 实现一个Stable Diffusion UI,使用 rust 调用Stable Diffusion执行任务
  • 交互上,继承会话的交互方式

效果图

添加一个制作的“会话”

1684544319672.jpg

主页面

1684544257051.jpg

1684544563004.jpg

后端

思路简述

  • 抽象一个能力模型,桌面版的执行环境拥有一些能力(例如Stable Diffusion的能力),这个在软软 AI 的“算力”这里。
  • 调用能力,用来执行任务。一个任务调度的模块。
  • Stable Diffusion UI 生成这样一个任务,并执行。
  • 执行的的结果中的大文件部分保存到之前的 IPFS中,一些任务相关的信息当前存储在内存中,后续可以考虑存储在 sqlite 中。如果是远程的任务(任务悬赏),所有的相关信息在任务悬赏平台中。

能力模型

CREATE TABLE rrai_abilities (
    `id` INTEGER PRIMARY KEY,
    `is_available` INTEGER DEFAULT 0,
    `ability` TEXT DEFAULT '',
    `ability_name` TEXT DEFAULT '',
    `version` TEXT DEFAULT '',
    `version_infor` TEXT DEFAULT '',
    `icon` TEXT DEFAULT '',
    `dependencies` TEXT DEFAULT '',
    `category` TEXT DEFAULT '',
    `settings_schema` TEXT DEFAULT '',
    `install_guide` TEXT DEFAULT '',
    `settings` TEXT DEFAULT '',
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(`ability`) ON CONFLICT REPLACE
);

CREATE TRIGGER rrai_abilities_updated AFTER UPDATE ON rrai_abilities 
BEGIN
UPDATE rrai_abilities SET updated_at = CURRENT_TIMESTAMP WHERE id = new.id;
END;

能力应该有发现、校验、调用等机制。

代码结构如下图:

1684545151077.jpg

  • abilities下一些能力
  • migration 是 sqlite 的脚本
  • tasks 是任务调度
  • workspaces 是类似代码中的工程管理

Stable Diffusion能力部分

1684545333889.jpg


pub async fn perform_task(args: &String) -> Result<String> {
    //获取配置信息
    let settings_values = crate::abilities::abilities_service::query_ability_settings(
        &String::from(crate::constants::STABLE_DIFFUSION_ABILITY_NAME),
    )
    .await?;

    //获取到
    if let Value::String(path_str) = settings_values
        .get(&String::from("model_path"))
        .map_or(Err(anyhow!("")), |path| Ok(path))?
    {
        // path_str
        tracing::debug!("model_path:{}", path_str);
        //args 反序列化
        let args_value: Value = serde_json::from_str(args)?;

        let workspace = crate::workspaces::Workspace::create()?;
        let workspace_path = workspace.path()?;
        tracing::debug!("workspace_path:{}", workspace_path);

        let mut context = Context::from_value(args_value)?;
        context.insert("model_path", &path_str);
        context.insert("workspace_path", &workspace_path);

        let code =
            Tera::one_off(include_str!("main.py"), &context, false).map_err(|err| anyhow!(err))?;

        //创建目录,并写入文件
        workspace.add_file("main.py", &code)?;
        workspace.mkdirs("outputs")?;

        let test_command = format!("python3 {}{}", workspace_path, "/main.py");
        tracing::debug!("test_command:{}", test_command);
        //
        let running_id = async_execute_command(&test_command).await?;
        tracing::debug!("返回执行命令的id:{}", running_id);
        Ok(running_id)
    } else {
        Err(anyhow!("没有配置信息"))
    }
}

任务执行时获取到配置的信息,创建一个workspace,将python 的代码通过模板引擎植入一些配置和任务的变量。将 workspace 构建完成之后,调用 python 的命令进行执行。 执行作为一个后台任务进行查看结果。

任务调度

任务调度的代码详见 github

github.com/rrkeji/rrai…

前端

前端代码结构

1684545758551.jpg

详细的代码参见 github

github.com/rrkeji/rrai…

(当前代码实现的部分逻辑,待完善)