东莞建设网站的位置,wordpress制作博客,高档网站建设公司,公众号怎么开通原创一、背景介绍
Flux 模型#xff1a;小模型高效生成高质量图像的基础
Flux 虽是百亿级参数的大模型家族#xff0c;但其中的轻量化变体#xff08;如 Flux.1 (schnell)#xff09;以及核心技术#xff0c;为小尺寸模型提供了高效生成的范式。其关键技术优势适配小模型的优…一、背景介绍Flux 模型小模型高效生成高质量图像的基础Flux 虽是百亿级参数的大模型家族但其中的轻量化变体如 Flux.1 (schnell)以及核心技术为小尺寸模型提供了高效生成的范式。其关键技术优势适配小模型的优化需求具体体现在两点。一是采用 Rectified Flow校正流技术拉直了传统扩散模型从噪声到图像的生成路径将生成过程优化为近似直线的最短路径大幅减少采样步数。像 Flux.1 (schnell) 仅需 4 步左右采样就能生成合理图像这对小模型而言意味着在降低计算成本的同时还能避免多步迭代带来的精度损耗。二是创新的多模态融合架构通过双文本编码器CLIPT5精准解析文本语义再结合双流转单流的 Transformer 注意力机制实现文本与图像特征的深度交互。这种设计让小模型无需复杂结构就能高效捕捉图文关联提升生成图像的内容一致性。DanceGRPO 框架通过强化学习进一步提升小模型性能DanceGRPO 是专门针对视觉生成领域 RLHF 方案不成熟的问题设计能精准解决小模型训练中质量提升的核心痛点具体优势有三。其一兼容性强适配 Flux 的核心范式。该框架创新性地将扩散模型和校正流模型如 Flux统一视为随机插值的特殊情况二者的采样过程均可通过 SDE 实现这让它能无缝对接 Flux 模型针对性地开展强化学习优化无需对 Flux 的基础架构做大幅修改降低了小模型适配强化学习的成本。其二显存压力低适配小模型训练资源限制。此前 ReFL 等强化学习方案需对奖励模型和 VAE 解码特征反向传播在视频生成等场景中显存压力极大根本不适合小模型。而 DanceGRPO 通过采样部分时间步加速训练、去除作用不大的 KL 散度正则项等设计大幅降低了计算和显存开销同时还能让小模型在更多提示词样本上学习提升泛化能力。其三强化学习效果显著精准优化核心指标。该框架通过多奖励模型叠加图像美感、图文匹配等五类指标让小模型能针对性提升薄弱项同时通过固定初始化噪声、控制梯度更新频率等优化手段避免训练中的奖励作弊和多样性下降问题。强化学习框架对比二、环境依赖三、DanceGRPOFLUX 整体流程推理阶段去噪生成图片用于训练过程观察**加载文本信息**获取初始数据将数据复制成 N 份作为输入。**去噪**生成初始噪声input 和当前噪音输入到 policy mode 预测噪声成分去噪生成 latents。**图片生成保存**基于推理阶段输出 latents经过 vae mode 解码成 image保存为文件用于观察过程。关键点推理去噪生成图像该模型中默认一组生成 12 哥样本即一个 prompt 会生成 12 哥大体相似而细节不同的图像每个图像默认经过 16 步迭代去噪生成。去噪步长步长随时间步长从大到小因为初始噪声成分较多相当于勾勒轮廓去噪步长可以大些后面要收敛到正确终点相当于描绘细节需要慢慢去噪。图像多样性去噪过程会加入随机扰动局部优化因此会有一组默认 12 张图片每张整体相似而细节有差异的图片一组内会进行对比提升优势动作的概率。Reward 阶段jisaunq reward 值**计算奖励值**image 和 prompt 输入到 reward model计算得到 reward 值。**计算相对优势值**计算 reward 的组内平均值每个 reward 和平均值比较得到 advantage组内相对优势。reward 详细流程计算 reward 值基于 prompt图例阶段得到的完全去噪的 image 值输入到 reward mode 中经过一系列计算得到每个 image 的 reward 值。计算 advantage 值reward 值经过组内平均得到平均值再用每个 iamge 的 reward 值和平均值对比得到 advantage 相对优势值。训练阶段计算 loss更新梯度**记录去噪过程**前面步骤会记录每个样本的去噪过程状态包括 reward 值advantag 值log_p 值代表当时策略的对数。**计算新策略对数**此时 policy model 会生成新预测值根据新预测值计算出 new_log_p 值代表新策略的对数。**计算旧策略比率**f(new_log, old_log) ratio代表某行为在新旧策略的概率比。**计算 loss 值**基于 ratio 和 advantage 计算出 loss 值。训练详细流程loss 是基于 advantage 和 ratio 计算得出的当 advantage 和 ratio 处于不同值时代表不同的含义advantageratio含义01该动作为优势动作且新策略该动作概率更大新策略正确的提升了该动作的概率新策略更优01该动作为优势动作且新策略该动作概率更小新策略错误的抑制了优势动作后续需要提高 ratio第一次计算 loss 时policy mode 还没有更新权重此时 new_log_p 和 old_log_p 实际上是一样的就是虽然定义上是新旧策略但实际上新旧策略的权重一样。loss 值会基于 advantage 和 ratio 一并计算所以开始的 loss 值依赖于样本的 advantage 值默认的梯度更新频率为 4 哥样品一次当处理本组第四个样品后 ratio 就会开始变化了。存在两个 loss 值clipped_loss 和 unclipped_loss都是基于 advantage 和 ratio 计算得到的但是 clipped_loss 的计算中加入了 clip_range约束了最终计算值的范围防止局部过度优化。四、模型部署流程拉取代码GitHub - XueZeyue/DanceGRPO: An official implementation of DanceGRPO: Unleashing GRPO on Visual Generationgitclone https://github.com/XueZeyue/DanceGRPO.git下载权重FLUXhttps://huggingface.co/black-forest-labs/FLUX.1-devHPShttps://huggingface.co/xswu/HPSv2/tree/mainopen_cliphttps://huggingface.co/laion/CLIP-ViT-H-14-laion2B-s32B-b79K/tree/main其它依赖安装仓库未实现懒加载所以会导入许多用不到的三方库可以直接注释避免引入太多无用的依赖耗费开发时间。一些为调用的接口也可以进行规避例如 flashatth 三方库接口等。# DanceGRPO/fastvideo/models/mochi_hf/modeling_mochi.py# 注释掉以下from liger_kernel.ops.swigluimportLigerSiLUMulFunction;flash_attn_no_pad.py# flash_attn_no_pad.py# 注释掉flash_attn的导包flash_attn_no_pad注释掉中间逻辑直接return执行安装脚本./env_setup.sh fastvideo修改font stylecolor:rgb(37, 43, 58);background-color:rgb(246, 247, 249);preprocess_flux_embedding.py/font# # 引入torch_npuimporttorch_npu from torch_npu.contribimporttransfer_to_npu# ./data/flux写死的路径改成参数# 原 pipe FluxPipeline.from_pretrained(./data/flux, torch_dtypetorch.bfloat16).to(device)pipeFluxPipeline.from_pretrained(args.model_path,torch_dtypetorch.bfloat16).to(device)修改font stylecolor:rgb(37, 43, 58);background-color:rgb(246, 247, 249);train_grpo_flux.py/font# # 引入torch_npuimporttorch_npu from torch_npu.contribimporttransfer_to_npu执行 Flux GRPO 脚本bash./scripts/finetune/finetune_flux_grpo.sh五、模型验证验证流程将 GRPO 的推理、reward、训练三个阶段单独抽离对齐再进行全流程验证采用“分 - 合” 验证策略单独阶段对齐能隔离不同模型和框架的差异聚焦每个环节的前向计算准确性比如推理阶段的动作生成、reward 阶段的评分计算、训练阶段的梯度更新避免因单个阶段误差累积掩盖问题。全流程对齐则能验证阶段间数据传递的一致性尤其要关注跨框架交互时的数据格式、精度损失等细节。记录关键节点的对齐数据如中间特征、概率分布、loss 值、梯度等既能作为阶段验证的基准也能在全流程中快速定位误差来源。随机性固定load 版本准确但麻烦通过torch.save、torch.load的方式将程序中涉及随机性的变量在 NPU 和 GPU 上保持一致。关闭shuffle固定训练的数据顺序# fastvideo/train_grpo_flux.py中shuffle设为falsesamplerDistributedSampler(train_dataset,rankrank,num_replicasworld_size,shuffleFalse,seedargs.sampler_seed)prev_sample 固定GPU代码修改如下在GPU上运行后保存下来# 1. 添加全局变量COFF_STEP控制coff生成的step数COFF_STEP0def flux_step(): global COFF_STEP......ifgrpo and prev_sample is None: cofftorch.randn_like(prev_sample_mean)torch.save(coff, fsaves/coff_{COFF_STEP}_{torch.distributed.get_rank()}.pt)prev_sampleprev_sample_mean coff * std_dev_t COFF_STEP12. NPU 上加载cofftorch.load(fsaves/coff_{COFF_STEP}_{torch.distributed.get_rank()}.pt,map_locationfcuda:{torch.cuda.current_device()})input_latents 固定GPU代码修改如下在GPU上运行后保存下来def sample_reference_model(args, device, transformer, vae, encoder_hidden_states, pooled_prompt_embeds, text_ids, reward_model, tokenizer, caption, preprocess_val, step,# # # 增加参数输入用于序列文件记录找到相关调用处加上该入参)def train_one_step(args, device, transformer, vae, reward_model, tokenizer, optimizer, lr_scheduler, loader, noise_scheduler, max_grad_norm, preprocess_val, step,# # # 增加参数输入用于序列文件记录找到相关调用处加上该入参)def sample_reference_model();......ifargs.init_same_noise: input_latentstorch.randn((1, IN_CHANNELS, latent_h, latent_w),# c,t,h,w)devicedevice,dtypetorch.bfloat16,)torch.save(input_latents, fsaves/input_latents_{step}_{torch.distributed.get_rank()}.pt)2. NPU上加载input_latentstorch.load(fsaves/input_latents_{step}_{torch.distributed.get_rank()}.pt,map_locationfcuda:{device})perms 固定GPU代码修改如下在GPU上运行后保存下来def train_one_step():......permstorch.stack([torch.randperm(len(samples[timesteps][0]))for_inrange(batch_size)]).to(device)torch.save(perms, fsaves/perms_{step}_{torch.distributed.get_rank()}.pt)2. font stylecolor:rgb(37, 43, 58);NPU上加载/fontpermstorch.load(fsaves/perms_{step}_{torch.distributed.get_rank()}.pt,map_locationf{device})使用 CPU 进行随机性固定固定seed可用于模型训练复现但是不同的设备如GPU和NPU在同样的seed下生成的值也是不一样的但是不同设备上都有CPU因此可以固定seed后使用CPU生成张量以此让GPU和NPU上生成的张量输入保持相同fastvideo/train_grpo_flux.py:91修改为ifgrpo and prev_sample is None: prev_sampleprev_sample_mean torch.randn_like(prev_sample_mean.cpu()).to(prev_sample_mean.device)* std_dev_tfont stylecolor:rgb(59, 62, 85);fastvideo/train_grpo_flux.py:270/font修改为ifargs.init_same_noise: input_latentstorch.randn((1, IN_CHANNELS, latent_h, latent_w),# c,t,h,w)dtypetorch.bfloat16,).to(device)fastvideo/train_grpo_flux.py:657修改为samplerDistributedSampler(train_dataset,rankrank,num_replicasworld_size,shuffleFalse,seedargs.sampler_seed)fastvideo/train_grpo_flux.py:1061增加importrandom def seed_all_own(seed1234,modeTrue,is_gpuTrue): random.seed(seed)os.environ[PYTHONHASHSEED]str(seed)os.environ[GLOBAL_SEED]str(seed)np.random.seed(seed)torch.manual_seed(seed)torch.use_deterministic_algorithms(mode)ifis_gpu: os.environ[CUBLAS_WORKSPACE_CONFIG]:4096:8os.environ[CUDA_LAUNCH_BLOCKING]1torch.cuda.manual_seed_all(seed)torch.cuda.manual_seed(seed)torch.backends.cudnn.deterministicTrue torch.backends.cudnn.enableFalse torch.backends.cudnn.benchmarkFalse else:importtorch_npu os.environ[HCCL_DETERMINISTIC]trueos.environ[CLOSE_MATMUL_K_SHIFT]1torch_npu.npu.manual_seed_all(seed)torch_npu.npu.manual_seed(seed)print( seed all )seed_all_own(is_gpuFalse)from msprobe.pytorchimportseed_all seed_all(modeTrue)推理流程对齐推理流程对齐的内容主要是 GRPO 去噪后生成的 latentslatents 解码成图片后对比固定随机性将GPU、NPU上使用相同noise的latents使用vae解码再保存此时只需要对比生成图片的差异。 关键代码decoded_image[0].save(img_path)这里会保存训练过程中模型在每个step,每次generation中生成的图片可以直观的看到训练过程中的的变化。# # # # sample_reference_model函数def sample_reference_model(): with torch.inference_mode(): with torch.autocast(cuda,dtypetorch.bfloat16): latentsunpack_latents(latents, h, w,8)latents(latents /0.3611)0.1159imagevae.decode(latents,return_dictFalse)[0]decoded_imageimage_processor.postprocess(image)decoded_image[0].save(f./images/flux_{step}_{rank}_{index}.png)Reward Model 对齐DanceGRPO 模型涉及多个 model强化学习中需要对齐的主要是loss和reward值这里讲的是如何对齐reward。此处采取的方法是把reward model单独拿出来for循环多步对比GPU和NPU的值reward值代码修改如下forstepinrange(1,1001):# text tokenizer([batch_caption[0]]).to(devicedevice, non_blockingTrue)imagetorch.load(f/home/grpo/DanceGRPO/save/images-1/image_{step}_{rank}.pt)texttorch.load(f/home/grpo/DanceGRPO/save/texts-1/text_{step}_{rank}.pt)# torch.save(image, f/home/GRPO/DanceGRPO/save/images-1/image_{step}_{rank}.pt)# torch.save(text, f/home/GRPO/DanceGRPO/save/texts-1/text_{step}_{rank}.pt)ifrank0: print(fimage_{rank}_{step}: , image,\n\n)print(ftext_{rank}_{step}: , text,\n\n)with torch.no_grad(): with torch.amp.autocast(cuda): outputsreward_model(image, text)ifrank0: print(foutput_{rank}_{step}: , outputs,\n\n)image_features, text_featuresoutputs[image_features], outputs[text_features]logits_per_imageimage_features text_features.T hps_scoretorch.diagonal(logits_per_image)all_rewards[]all_rewards.append(hps_score)all_rewardstorch.cat(all_rewards,dim0)samples{rewards:all_rewards.to(torch.float32)}ifrank0: print(fsamples_{rank}_{step}: , samples,\n\n)gathered_rewardgather_tensor(samples[rewards])ifrank0: print(fgather_reward_{rank}_{step}: , gathered_reward,\n\n)ifdist.get_rank()0: print(gathered_hps_reward, gathered_reward)with open(./hps_reward.txt,a)as f: f.write(f{gathered_reward.mean().item()}\n)samples_batched{k: v.unsqueeze(1)fork,vinsamples.items()}samples_batched_list[dict(zip(samples_batched, x))forxinzip(*samples_batched.values())]fori, sampleinlist(enumerate(samples_batched_list)):ifrank0: print(fsample_{rank}_{step}: , sample[rewards],\n\n)ifdist.get_rank()%80: print(hps reward, sample[rewards].item(),\n\n\n\n\n)# print(ratio, ratio)# print(advantage, sample[advantages].item())# print(final loss, loss.item())生成1000个reward值其精度对比效果如下绝对误差≈0.015%数据、图片来自昇腾官方数据。端到端对齐对齐标准固定随机性后需要按照如下标准关注对齐结果关注推理阶段生成的图片主观对齐关注训练过程中的loss生成模型loss较小参考价值有限关注reward scores200步误差5%以内对齐步骤端到端对齐流程主要关注两方面一方面是综合度量模型训练的指标推理阶段图片lossrward scores另一方面是下游任务推理效果。全流程对齐具体步骤两边加载相同的预训练权重。固定随机性整体随机性与确定性计算固定seed_all,modeTruenoise在cpu侧生成。保存关键信息推理阶段的图片、reward阶段的rewardvalues、训练阶段模型loss同时保存权重用于对齐推理效果此处注意需要持续关注推理阶段生成图片的效果具体例子为在替换rope融合算子时loss结果与reward差异不大但推理阶段出现了花图。端到端流程结构六、常见问题如遇到ROPE部分不支持complex128计算问题NPU场景需要适配修改___CODE_BLOCK_PLACEHOLDER___211250行is_mpsids.device.typempsis_npuids.device.typenpu#增加改行##下面增加is_npu判断freqs_dtypetorch.float32ifis_mps or is_npuelsetorch.float64七、总结DanceGRPOFLUX 模型在 AI 生图领域解决 FLUX 在生成过程中与人类审美、语义对齐等方面的适配问题大幅提升其生图质量与稳定性。展望未来多模态生成强化学习模型有望在更多领域开花结果如影视特效制作中实现更逼真的虚拟场景与角色创建教育领域中打造沉浸式的学习环境医疗领域辅助医生进行手术模拟与病情可视化分析等 。同时随着技术发展模型将不断优化生成效率与质量进一步提升在处理复杂任务、理解模糊指令等方面取得更大突破为各行业数字化转型与创新发展注入强大动力 。注明昇腾PAE案例库对本文写作亦有帮助。