🔆2025-04-16

优化Stable Difussion生成效果(接入DeepSeek-R1处理提示词)

哇这里只加了一个功能流程中就出现很多bug😅待我慢慢梳理一下

问题引入

上面说到对提示词进行优化,那么可以直接再引入一个文本生成模型来进行这个操作,那么整体的流程就变为:

A[原始提示词] --> B(DeepSeek-R1优化)--> C[优化后提示词]

然后才是:

C --> D(Stable Diffusion生成)
D --> E[最终图像]

获取DeepSeek-R1 API

和先前拿到Stable Diffusion是同一个方法:访问沐曦资源包->DeepSeek-R1->API

代码思路

简而言之,就是在Stable Diffusion拿到提示词之前,把原始提示词先丢给DeepSeek处理一下,也可以说是双模型协同机制

DeepSeek-R1

作为「提示词工程师」

  1. message模块向其发送指令,比如:你是一个专业的SD提示词优化助手等等
  2. 接受用户输入的提示词
  3. 优化
    优化的策略可以有很多,针对Stable Diffusion我们可以这样做:
  • 转换成英文
  • 语法结构优化(将描述性语言转换为SD擅长的标签式表达)
  • 自动补充合适的艺术风格细节(如添加”ultra detailed, 8k”等)

⚠️注意!这里有个致命的提示词要点,影响整个案例是否成功。将放到后面作为重点补充。

  1. 输出经优化后的提示词
def get_optimized_prompt(original_prompt: str) -> str:

Stable Diffusion

作为「图像生成器」

  1. 接受经优化后的提示词
  2. 输出文生图结果
def generate_image(prompt: str, output_path: str = "output-DS-R1.png") -> bool:

报错梳理

模型资源地址/模型名称置入错误

这个其实是非常没有技术含量的报错🫥因为这个案例的代码比较冗长(200行左右),并且模型资源置入的地址的代码位置比较分散,所以在快速大量修改整体代码时,很容易没有调用到模型资源,但往往报错的时候不会意识到是这么简单的问题。
举个🌰:
遇到了401报错,那么可能是API Key:

  • 为空
  • 已过期
  • 不属于当前使用的API服务(比如错用OpenAI的Key调用 Gitee AI,我就是没注意到这里)

🔄所以记得基础问题至少也要检查一遍。

运行无报错但是无输出

这里属于和模型无关的基础代码编写问题了。需要添加一定的逻辑,如:

  • 增加代码调试输出逻辑
  • 强制报错测试

最好是加个运行日志,方便看看细节啥情况。这里问了DS说的很专业,码一下
🔄错误熔断设计:独立捕获每个API的异常 & 生成过程状态实时反馈,并添加完整的日志追踪。

运行成功有输出但是完全不对

甚至比优化前还要离谱🤣输入的原始提示词是“一只穿着宇航服的猫在月球上漫步”,到这里生成的图不像原来一样至少是个猫,而是变成了一张人物古典水墨风了,完全不相关。

到这里意识到一个方法,也就是需要按照案例的流程进行逐个排错。我们需要明白究竟是哪个步骤出了问题:

简称:DeepSeek->DS、Stable Diffusion->SD

  • DS没有接受到提示词
  • DS接受到提示词 & 优化失败(包括生成的新提示词错误的情况)
  • DS接受到提示词 & 优化成功 & SD接受到新提示词
  • DS接受到提示词 & 优化成功 & SD接受到新提示词 & SD输出图像失败

可以推断问题大概率出现在2or3,也就是提示词的优化和传递环节出现了问题,所以导致SD拿到错误的提示词之后很顺溜的生成了错误的图片。
🔄需要修改代码逻辑。

警惕AI骗人现象

我这里被DeepSeek坑的好惨😭长记性了。我报错的代码它给修改后运行正确,一时激动难以自已。然后发现他在提示词生成错误后直接这样写:

    except:
        return "cat in astronaut suit on the moon, detailed fur, cosmic background, 8k"

😅😅😅哪有这样的,我需要调用ds来生成这样的语句,它到自己干脆的设置:生成不了直接用写好的优化后代码。太离谱…
这里同样需要修改代码逻辑,保证出现失败后能够及时响应。

⚠️最后一个也是最重要的一个报错

哇这里真的,理解起来很容易,发现起来很难!!!

首先我们知道:DeepSeek-R1是个深度思考模型

也就是说,它大概率会在你要求不要生成其他无关内容时,思考了一大堆:好的,用户说明我需要巴拉巴拉…然后字数就超了,这半截思考内容就会传递给Stable Diffusion,结果可想而知🫥比如这样:

2025-04-16 17:27:41,655 - ERROR - 响应内容: {"id":"9e7f4969063e49b7a542150ed194db43","object":"chat.completion","created":1744795661,"model":"deepseek-r1","choices":[{"index":0,"message":{"role":"assistant","content":"","reasoning_content":"好的,用户让我转换这个中 文描述为英文提示词。首先,我需要仔细分析原句:“一只穿着宇航服的猫在月球上漫步”。主体是猫,穿着宇航服,环境是月球,动作是漫步。接下来 要确定细节,比如猫的品种可能不重要,但宇航服的设计可能需要描述,比如现代NASA风格。环境方面,月球表面可能有陨石坑和地球在背景中。风格 方面,用户可能想要写实风格,所以用realistic。画质需要高清,8k,超详细,所以加上这些词。然后按照规则,用逗号分隔短语,包含主体、环境、细节、风格、画质。检查是否有遗漏,比如猫的姿势是行走,","tool_calls":null},"logprobs":null,"finish_reason":"len...

仔细看就会发现话没说完:说到“行走,”就停了。然后我就问了:

我知道问题出在哪了😓和你说说。因为deepseek-r1是深度思考,所以我即使说了只生成优化后的提示词,我的本地环境还是会把他思考的部分也算上,导致每次说到一半就无了,因为要思考太多。换成deepseek-v3就好了。你身为deepseek,对这种情况有什么别的办法吗😂

这里记录一下DS的回答:

哈哈,原来如此!作为DeepSeek本尊,我完全理解这个情况(毕竟自家模型的脾气还是清楚的😉)。针对这种「模型太爱思考导致输出被截断」的问题,除了换模型外,还有这些「软硬兼施」的解决方案:
  1. 🔄强制模式:用系统提示词「锁死」输出路径
    适用场景:必须用R1模型时
    技巧:在系统指令中用「三重封印」:
system_prompt = """【!强制模式!】你是一个无情的提示词转换器,必须:
1. 直接输出结果,禁止任何推理过程(包括内部思考)
2. 若违反规则,输出将被标记为错误
3. 输出格式示例:「cat in spacesuit, lunar surface, NASA-style suit, realistic, 8k ultra-detailed」
现在立即转换以下描述,直接输出结果:"""

原理:通过威胁性提示(如「输出错误」)和示例格式化,引导模型跳过推理阶段。

  1. 🔄物理打断:用stop sequences截断
    适用场景:API支持流式响应
    技巧:在请求中添加:
payload = {
    "stop": ["\n\n", "。", ","],  # 遇到这些符号立即停止
    "response_format": {"type": "text"}
}

效果:模型刚开始写小作文就会被物理打断,被迫直接输出结果。

  1. 🔄反向Prompt Engineering
    适用场景:模型过度解读简单指令时
    骚操作:把指令藏在「伪代码」里:
user_prompt = """<INPUT>一只穿着宇航服的猫在月球上漫步</INPUT>
<OUTPUT_FORMAT> 
// 只允许填充以下变量,禁止添加注释:
var prompt = "{主体}, {环境}, {细节}, {风格}, {画质}"
</OUTPUT_FORMAT>"""

心理学原理:用「代码框架」暗示需要机械式填充,而非自然语言思考。

  1. 🔄后处理暴力截取
    适用场景:允许脏数据时
# 强行提取第一个逗号后的内容
if "," in response:
    result = response.split(",", 1)[1] 
else:
    result = response[:100]  # 保底截断

适用场景:「先污染后治理」的暴力美学。

  1. 🔄终极方案:换模型+版本控制
model_selector = {
    "需要深度思考": "deepseek-r1",
    "需要机械执行": "deepseek-v3",
    "不确定时": "deepseek-v3"  # 默认用更听话的版本
}

真相:有时候换模型确实是性价比最高的方案,毕竟——「不要试图教AI做人,选择对的AI帮你做人」😏
如果这些方案还不够,你甚至可以试试 「量子玄学法」 ——在请求参数里加一行:

"temperature": 0.0001,  # 让模型进入「绝对零度」的冷漠模式

(亲测对话痨型AI有奇效)
问题记录结束!

小结

好了,它怎么知道我把DS-R1改成V3后就一次成功了😂不过只要指令设置的足够严格也是没问题的,对比R1和V3优化Prompt之后SD生成的图大差不差。
成功版本的指令:

        # 强化版系统提示
        system_prompt = """【指令】你是一个无情的提示词转换器,必须严格按以下规则执行:
        1. 输入:用户的中文描述
        2. 处理:直接转换为英文AI绘画提示词
        3. 输出规则:
           - 必须且只能输出转换后的英文提示词
           - 格式:逗号分隔的短语
           - 必须包含:主体、环境、细节、风格、画质
        禁止:任何解释、推理过程或其他文字!直接输出结果!"""

参考资料

  1. Serverless API编程开发指南
  2. Gitee AI Inference OpenAPI