SIGIR 2025端到端生成式推荐ETEGRec
文章目录
- 1. 背景
- 2. 方法
- 2.1 框架图
- 2.2 问题定义
- 2.3 Item Tokenizer
- 2.4 Generative Recommender
- 2.5 ⭐️Sequence-Item Alignment
- 2.6 ⭐️Preference-Semantic Alignment
- 2.7 交替优化
- 3. 总结
现阶段 GRM 大多是两阶段的模型,第一阶段进行内容理解-行为语义对齐,对item进行内容表征,并基于RQ-VAE或类似架构构建离散token;第二阶段通常是基于Transformer的生成式模型,是模型具备用户行为理解能力与item生成能力。本文发表于SIGIR 2025,是针对这两阶段进行融合,提出一个端到端的可学习生成式推荐框架。
论文名称:《Generative Recommender with End-to-End Learnable Item Tokenization》
论文地址:https://arxiv.org/pdf/2409.05546
1. 背景
本文是针对生成式推荐的,区别于传统的判别式推荐(先算一堆物品和用户历史行为的相似度,再挑选最相似的)。生成式推荐将推荐看做序列生成任务,逐步生成要推荐的物品标识符。这个过程涉及两个关键阶段:
- 物品标记化(Item Tokenization):为每个物品生成一串**有语义的 **token(不是id)。不能使用原始 ID 作为唯一编号,因为推荐领域的物品太多,并且动态增长,不像 NLP 领域中的词汇数量固定。
- 自回归生成(Autoregressive Generative):逐步生成用户可能喜欢的下一个物品 token 。
对于第一阶段目前的研究主要有:无参数方法(parameter-free):比如用共现矩阵、文本特征、聚类等。深度学习方法:比如用向量量化(VQ)方法来学习每个物品的语义 token(RQ-VAE)。
对于第二阶段目前大多采用 T5 这种 encoder-decoder 架构,它在文本生成类任务表现好,所以被用来推荐中的序列建模。也有decoder-only 架构。
但目前的两阶段范式中,两个阶段是分开训练的,也就是说现训练一个物品标记器 --> 然后固定不动 --> 再去训练生成推荐器。
存在问题:
- 第一阶段学出来的 token 并不一定适合用来推荐。
- 第二阶段无法进一步优化这些 token 表示,丧失深入理解的机会。(这里应该不能强行训练 codebook 吧?)
本文尝试让物品标记器(第一阶段)与生成器(第二阶段),协同工作,一起训练,一起优化,实现”无缝集成“。【通过引入两个对齐机制】
2. 方法
2.1 框架图
ETEGRec 框架由两个主要组件组成:物品标记器和生成式推荐器。物品标记器采用 RQ-VAE,将每个物品编码为一组离散的 token 序列,用于输入推荐器。生成式推荐器基于 Transformer,根据用户的历史交互 token 序列自回归地生成目标物品的 token,用于预测下一个推荐项。为实现两个模块的协同优化,框架引入了两个对齐机制:序列-物品对齐(c)通过最小化推荐器生成的行为序列分布与目标物品 token 分布之间的 KL 散度,确保结构上的一致性;偏好-语义对齐(d)则通过对比学习方式,将用户偏好表示与目标物品的语义向量进行对齐,实现语义层级上的匹配。整个系统通过联合优化 token 重构损失、生成损失以及两个对齐损失,实现端到端的高效推荐。
2.2 问题定义
P ( Y ∣ X ) = ∏ l = 1 L P ( c l t + 1 ∣ X , c 1 t + 1 , … , c l − 1 t + 1 ) P(Y|X) = \prod_{l=1}^{L} P(c_l^{t+1} \mid X, c_1^{t+1}, \ldots, c_{l-1}^{t+1}) P(Y∣X)=l=1∏LP(clt+1∣X,c1t+1,…,cl−1t+1)
解释:该公式表示将推荐任务建模为一个序列到序列的生成问题,即在给定用户历史交互序列的 token 表示 X X X 的基础上,模型自回归地逐个生成下一个物品 i t + 1 i_{t+1} it+1 的 token 序列 Y = [ c 1 t + 1 , … , c L t + 1 ] Y = [c_1^{t+1}, \ldots, c_L^{t+1}] Y=[c1t+1,…,cLt+1],每个 token 的生成都依赖于历史输入和当前已生成的 token,codebook为 L L L 层。
2.3 Item Tokenizer
这部分就是经典的 RQ-VAE(Residual Quantization Variational AutoEncoder) 的方法实现物品标记器(item tokenizer),旨在将每个物品的语义表示编码为一组离散 token,以供生成式推荐器使用。该方法能够将连续的语义向量压缩为多级离散 token 序列,从而实现结构紧凑、语义可控的物品表示。
具体而言,给定某个物品 i i i 的原始语义表示 z ∈ R d s z \in \mathbb{R}^{d_s} z∈Rds,item tokenizer 首先通过一个多层感知机(MLP)编码器将其映射到潜在空间中,得到潜在表示:
r = Encoder T ( z ) r = \text{Encoder}_\mathcal{T}(z) r=EncoderT(z)
接着,使用 残差量化(Residual Quantization) 将 r r r 转化为一个由 L L L 个 token 组成的序列 [ c 1 , … , c L ] [c_1, \dots, c_L] [c1,…,cL],即:
[ c 1 , … , c L ] = T ( z ) [c_1, \dots, c_L] = \mathcal{T}(z) [c1,…,cL]=T(z)
残差量化的核心思想是:在每一层 l l l,我们从一个码本 C l C_l Cl 中选择最接近当前残差向量 v l v_l vl 的向量作为 token 对应的码本向量 e c l l e_{c_l}^l ecll。其中,初始残差为 v 1 = r v_1 = r v1=r,每一层的 token 通过如下方式选取:
c l = arg max k P ( k ∣ v l ) , P ( k ∣ v l ) = exp ( − ∥ v l − e k l ∥ 2 ) ∑ j = 1 K exp ( − ∥ v l − e j l ∥ 2 ) c_l = \arg\max_k P(k \mid v_l), \quad P(k \mid v_l) = \frac{\exp(-\|v_l - e_k^l\|^2)}{\sum_{j=1}^K \exp(-\|v_l - e_j^l\|^2)} cl=argkmaxP(k∣vl),P(k∣vl)=∑j=1Kexp(−∥vl−ejl∥2)exp(−∥vl−ekl∥2)
并更新残差向量为:
v l + 1 = v l − e c l l v_{l+1} = v_l - e_{c_l}^l vl+1=vl−ecll
通过 L 次迭代后,我们得到完整的 token 序列 [ c 1 , … , c L ] [c_1, \dots, c_L] [c1,…,cL],以及对应的量化表示:
r ~ = ∑ l = 1 L e c l l \tilde{r} = \sum_{l=1}^L e_{c_l}^l r~=l=1∑Lecll
为了使该 token 表达能够忠实反映原始语义,作者设计了两个联合优化的损失项构成的整体量化损失:
L S Q = L R E C O N + L R Q \mathcal{L}_{SQ} = \mathcal{L}_{RECON} + \mathcal{L}_{RQ} LSQ=LRECON+LRQ
其中,重构损失 L R E C O N \mathcal{L}_{RECON} LRECON 保证解码器从量化表示 r ~ \tilde{r} r~ 恢复出的语义向量 z ~ \tilde{z} z~ 接近原始向量 z z z:
L R E C O N = ∥ z − z ~ ∥ 2 , z ~ = Decoder T ( r ~ ) \mathcal{L}_{RECON} = \| z - \tilde{z} \|^2, \quad \quad \tilde{z} = \text{Decoder}_\mathcal{T}(\tilde{r}) LRECON=∥z−z~∥2,z~=DecoderT(r~)
而量化损失 L R Q \mathcal{L}_{RQ} LRQ 则同时优化编码器输出和码本,使它们彼此靠近:
L R Q = ∑ l = 1 L ∥ sg ( v l ) − e c l l ∥ 2 + β ∥ v l − sg ( e c l l ) ∥ 2 \mathcal{L}_{RQ} = \sum_{l=1}^L \| \text{sg}(v_l) - e_{c_l}^l \|^2 + \beta \| v_l - \text{sg}(e_{c_l}^l) \|^2 LRQ=l=1∑L∥sg(vl)−ecll∥2+β∥vl−sg(ecll)∥2
其中 sg [ ⋅ ] \text{sg}[\cdot] sg[⋅] 是 stop-gradient 操作,避免反向传播干扰, β \beta β 为调节两项平衡的系数。
综上所述,该基于 RQ-VAE 的 item tokenizer 能够以端到端方式学习将物品语义向量映射为离散 token 序列,既保证表达能力,又具备良好的生成结构,对后续生成式推荐建模具有重要意义。
2.4 Generative Recommender
在 ETEGRec 中,生成式推荐器(generative recommender)负责根据用户的历史交互行为序列预测下一个用户可能感兴趣的物品,其核心采用类 T5 的 Transformer 编码器-解码器结构。整个任务被建模为一个 token-level 的 sequence-to-sequence 生成问题。具体来说,首先将用户历史交互序列 S = [ i 1 , . . . , i t ] S = [i_1, ..., i_t] S=[i1,...,it] 中的每个物品通过 item tokenizer 映射为固定长度为 L L L 的 token 序列,从而得到输入 token 序列 X = [ c 1 1 , c 2 1 , . . . , c L t ] X = [c_1^1, c_2^1, ..., c_L^t] X=[c11,c21,...,cLt]。同样,目标物品 i t + 1 i_{t+1} it+1 被映射为目标 token 序列 Y = [ c 1 t + 1 , . . . , c L t + 1 ] Y = [c_1^{t+1}, ..., c_L^{t+1}] Y=[c1t+1,...,cLt+1]。
在建模过程中,首先将输入 token 嵌入为向量表示 E X E^X EX 并送入编码器,得到历史行为的编码结果:
H E = Encoder R ( E X ) H^E = \text{Encoder}_\mathcal{R}(E^X) HE=EncoderR(EX)
其中 H E ∈ R ∣ X ∣ × d h H^E \in \mathbb{R}^{|X| \times d_h} HE∈R∣X∣×dh 是编码后的隐藏表示, d h d_h dh 是隐藏维度。在解码阶段,为了生成目标 token 序列,解码器以 H E H^E HE 和一个以特殊起始符 “[BOS]” 开头的目标序列作为输入:
Y ~ = [ [BOS] , c 1 t + 1 , . . . , c L − 1 t + 1 ] \tilde{Y} = [\text{[BOS]}, c_1^{t+1}, ..., c_{L-1}^{t+1}] Y~=[[BOS],c1t+1,...,cL−1t+1]
并生成输出表示:
H D = Decoder R ( H E , Y ~ ) H^D = \text{Decoder}_\mathcal{R}(H^E, \tilde{Y}) HD=DecoderR(HE,Y~)
其中 H D ∈ R ( L + 1 ) × d h H^D \in \mathbb{R}^{(L+1) \times d_h} HD∈R(L+1)×dh 是解码器每一步的隐藏状态,表示对目标 token 的逐步生成。
训练目标是最大化生成的目标 token 序列的对数似然概率,也即最小化如下的推荐损失:
L R E C = − ∑ j = 1 L log P ( Y j ∣ X , Y < j ) \mathcal{L}_{REC} = -\sum_{j=1}^{L} \log P(Y_j \mid X, Y_{<j}) LREC=−j=1∑LlogP(Yj∣X,Y<j)
其中 Y j Y_j Yj 表示目标 token 序列的第 j j j 个 token, Y < j Y_{<j} Y<j 表示之前已生成的 tokens,整个生成过程是自回归(autoregressive)的,每一步的预测依赖于之前所有的生成结果。
通过这种 token-level 生成建模方式,ETEGRec 能够直接生成未来推荐物品的 token 表达,实现了从用户行为到物品 token 的高效预测,且自然支持开放词表与泛化能力。
2.5 ⭐️Sequence-Item Alignment
如图红色的框,上面的就是用户的历史行为所表达出来的偏好,左下方的就是用户即将交互的目标物品的真实表示,这个对齐模块的核心就是:这两者在 tokenizer 看来表达应该是一致的。也就是说,虽然 z E z^E zE 与 z z z 来自不同的路径(一个是行为序列推理出来的,一个是目标物品embedding),但是他们在结构上具有一致的token概率分布,因为他们实际上指向的是同一个推荐目标。
SIA整体流程:
- H E H^E HE 是用户历史行为序列(即 token 序列 X X X)经过推荐器的 Transformer 编码器后得到的隐藏状态;
- 这个 H E H^E HE 表示整个序列的信息;
- 通过 mean pooling + MLP 得到一个紧凑的向量 z E z^E zE,可以看作是“用户的偏好表示”。
z E = MLP ( mean_pool ( H E ) ) z^E = \text{MLP}(\text{mean\_pool}(H^E)) zE=MLP(mean_pool(HE))
-
而 z z z 是目标物品本身的语义表示(embedding);
-
两者都输入相同的 item tokenizer(基于 RQ-VAE);
-
在每一层 l l l,两者都会被映射为同一个 codebook 的概率分布(即 soft assignment):
P z l 与 P z E l P_z^l \quad \text{与} \quad P_{z^E}^l Pzl与PzEl
- 然后对每一层的两个分布做对称的 KL 散度计算,构成序列-物品对齐的损失函数:
L S I A = − ∑ l = 1 L ( D K L ( P z l ∥ P z E l ) + D K L ( P z E l ∥ P z l ) ) \mathcal{L}_{SIA} = -\sum_{l=1}^L \left( D_{KL}(P_z^l \| P_{z^E}^l) + D_{KL}(P_{z^E}^l \| P_z^l) \right) LSIA=−l=1∑L(DKL(Pzl∥PzEl)+DKL(PzEl∥Pzl))
2.6 ⭐️Preference-Semantic Alignment
如图红色的框,上面推荐器Decoder输出的 H D H^D HD表示用户历史行为序列经过模型生成的表示,经过pooling获得其第一列向量 h D h^D hD(图中是 h E h^E hE 但是论文文字写的 h D h^D hD) ,就表示当前用户的行为偏好摘要表示,它体现了用户会喜欢什么。下面的红色框就是目标物品经过 item tokenizer之后得到的离散 token 然后将离散 token 送入 tokenizer 的 Decoder 重构出原始语义向量 z ~ \tilde{z} z~, z ~ \tilde{z} z~ 代表目标物品的重建语义表示,并天然包含了 tokenizer 学习到的结构信息。核心在于: h D h^D hD 是用户想要的, z ~ \tilde{z} z~ 是物品的真实语义。如果推荐器真的理解用户,那它生成的 h D h^D hD 应该“指向”目标物品的语义表示。
PSA整体流程:
- H D H^D HD 是用户历史行为序列经过推荐器的 Transformer 解码器后得到的隐藏状态;
- 取 H D H^D HD 的第一列 hidden state,并通过 pooling 操作(如 mean 或取第一位)获得用户偏好的最终表示 h D h^D hD;
- 此时 h D h^D hD 代表用户的“语义偏好向量”,用于表示“用户想要什么”;
- 同时,目标物品的表示 z z z 先通过 item tokenizer 进行残差量化,得到 token 序列 [ c 1 , . . . , c L ] [c_1, ..., c_L] [c1,...,cL];
- 然后这个 token 序列会被送入 tokenizer 的解码器中进行重构,得到重建语义表示 z ~ \tilde{z} z~:
z ~ = Decoder T ( ∑ l = 1 L e c l l ) \tilde{z} = \text{Decoder}_\mathcal{T}\left( \sum_{l=1}^L e_{c_l}^l \right) z~=DecoderT(l=1∑Lecll)
其中 e c l l e_{c_l}^l ecll 是第 l l l 层 codebook 中选出的 token 向量;
-
h D h^D hD 和 z ~ \tilde{z} z~ 分别代表“用户偏好语义”与“物品语义”,应当在语义空间中靠近;
-
使用 InfoNCE 对比学习 进行对齐,在一个训练 batch 中最大化 h D h^D hD 与对应 z ~ \tilde{z} z~ 的相似度,同时区分其他负样本,最终损失为:
L P S A = − ( log exp ( s ( z ~ , h D ) / τ ) ∑ h ^ ∈ B exp ( s ( z ~ , h ^ ) / τ ) + log exp ( s ( h D , z ~ ) / τ ) ∑ z ^ ∈ B exp ( s ( h D , z ^ ) / τ ) ) \mathcal{L}_{PSA} = -\left( \log \frac{\exp(s(\tilde{z}, h^D)/\tau)}{\sum_{\hat{h} \in \mathcal{B}} \exp(s(\tilde{z}, \hat{h})/\tau)} + \log \frac{\exp(s(h^D, \tilde{z})/\tau)}{\sum_{\hat{z} \in \mathcal{B}} \exp(s(h^D, \hat{z})/\tau)} \right) LPSA=−(log∑h^∈Bexp(s(z~,h^)/τ)exp(s(z~,hD)/τ)+log∑z^∈Bexp(s(hD,z^)/τ)exp(s(hD,z~)/τ))
其中 s ( ⋅ , ⋅ ) s(\cdot, \cdot) s(⋅,⋅) 是余弦相似度函数, τ \tau τ 是温度系数, B \mathcal{B} B 是当前 batch 样本集合。
2.7 交替优化
ETEGRec由两个独立模块组成 Item Tokenizer 与 Generative Recommender,这两个模块通过两个对齐损失 L S I A L_{SIA} LSIA 和 L P S A L_{PSA} LPSA连接,但如果一开始就联合训练两个部分,容易出现:参数震荡、不收敛、tokenizer质量低影响推荐,或 recommender 太强导致 tokenizer 学不到东西。作者采用交替优化的方式避免问题。
训练被分为多个周期(cycle),每个周期包含若干个 epoch。
-
每个周期的第一个 epoch:只优化 Item Tokenizer,冻结推荐器,让 tokenizer 更新得更适合当前 recommender。采用:
L I T = L S Q + μ L S I A + λ L P S A \mathcal{L}_{IT} = \mathcal{L}_{SQ} + \mu \mathcal{L}_{SIA} + \lambda \mathcal{L}_{PSA} LIT=LSQ+μLSIA+λLPSA- L S Q \mathcal{L}_{SQ} LSQ:tokenizer 本身的重构损失(token 生成 + embedding 重建);
- L S I A \mathcal{L}_{SIA} LSIA:结构对齐(序列→物品分布);
- L P S A \mathcal{L}_{PSA} LPSA:语义对齐(偏好→语义);
- μ , λ \mu, \lambda μ,λ:超参数,用来平衡三项损失的权重。
-
周期的剩余 epoch:只优化 Generative Recommender,冻结 tokenizer。保证在稳定 token 编码下训练 recommender,不被扰动,采用:
L G R = L R E C + μ L S I A + λ L P S A (18) \mathcal{L}_{GR} = \mathcal{L}_{REC} + \mu \mathcal{L}_{SIA} + \lambda \mathcal{L}_{PSA} \tag{18} LGR=LREC+μLSIA+λLPSA(18)- L R E C \mathcal{L}_{REC} LREC:推荐器生成 token 的序列建模损失(负 log-likelihood);
- 同样包含两项对齐损失;
- 但此时冻结 tokenizer,只训练 recommender。
3. 总结
最近也在看生成式推荐,这篇文章主要就是提出了两个对齐模块以及一个交替优化的训练方式,去解决传统的解耦问题,但是这样也就限制了生成式推荐模块必须是encoder-decoder架构,不能是decoder-only了吧。有一定的借鉴之处,整体看起来比较简单,就是 h D h^D hD 部分不是那么理解。
相关文章:
SIGIR 2025端到端生成式推荐ETEGRec
文章目录 1. 背景2. 方法2.1 框架图2.2 问题定义2.3 Item Tokenizer2.4 Generative Recommender2.5 ⭐️Sequence-Item Alignment2.6 ⭐️Preference-Semantic Alignment2.7 交替优化 3. 总结 现阶段 GRM 大多是两阶段的模型,第一阶段进行内容理解-行为语义对齐&…...
rust 中的 EBNF 介绍
在 rust 参考手册中,有大量类似: 句法 MacroInvocation :SimplePath ! DelimTokenTreeDelimTokenTree :( TokenTree* )| [ TokenTree* ]| { TokenTree* }TokenTree :Token排除 定界符(delimiters) | DelimTokenTreeMacroInvocationSemi :SimplePath ! (…...
解决 Redis 缓存与数据库一致性问题的技术指南
Redis 缓存与数据库一致性是分布式系统中常见的挑战,尤其在高并发场景下(如电商、用户管理、对账系统)。Redis 作为高性能缓存,常用于加速数据访问,但其与数据库(如 MySQL)之间的数据同步可能因…...
LlamaIndex 第六篇 SimpleDirectoryReader
SimpleDirectoryReader 是将本地文件数据加载到 LlamaIndex 的最简单方式。虽然在实际生产场景中,您更可能需要使用 LlamaHub 提供的多种数据读取器(Reader),但 SimpleDirectoryReader 无疑是快速入门的理想选择。 支持的文件类型…...
window 显示驱动开发-配置内存段类型
视频内存管理器(VidMm)和显示硬件仅支持某些类型的内存段。 因此,内核模式显示微型端口驱动程序(KMD)只能配置这些类型的段。 KMD 可以配置内存空间段和光圈空间段,其中不同: 内存空间段由保存…...
【人工智能学习之动作识别TSM训练与部署】
【人工智能学习之动作识别TSM训练与部署】 基于MMAction2动作识别项目的开发一、MMAction2的安装二、数据集制作三、模型训练1. 配置文件准备2. 关键参数修改3. 启动训练4. 启动成功 ONNX模型部署方案一、环境准备二、执行转换命令 基于MMAction2动作识别项目的开发 一、MMAct…...
PostgreSQL冻结过程
1.冻结过程 冻结过程有两种模式,依特定条件而择其一执行。为方便起见,将这两种模式分别称为惰性模式(lazy mode)和迫切模式(eager mode)。 并发清理(Concurrent VACUUM)通常在内部…...
SSHv2公钥认证示例-Paramiko复用 Transport 连接
在 Paramiko 中复用 Transport 连接时,若要通过 公钥认证(而非密码)建立连接,需手动加载私钥并与 Transport 关联。以下是详细操作步骤及完整代码示例: 步骤 1:加载私钥文件 使用 RSAKey 或 Ed25519Key 类…...
华为5.7机考-最小代价相遇的路径规划Java题解
题目内容 输入描述 输出描述 示例: 输入: 2 1 2 2 1 输出: 3 思路: Dijkstra 算法实现 dijkstra(int sx, int sy, int[][] dirs) 方法: 参数:起点坐标 (sx, sy) 和允许的移动方向 初始化࿱…...
element-ui分页的使用及修改样式
1.安装 npm install element-ui -S 2.在main.js中引入,这里是全部引入,也可以按需引入 import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css Vue.use(ElementUI) 3.使用 layout"prev, pager, next, jumper" :jumpe…...
[Unity]-[UI]-[Image] 关于UI精灵图资源导入设置的详细解释
Unity UI Sprite UI资源导入详解图片导入项目Texture TypeTexture ShapeAdvanced Setting 高级设置 图片设置案例常见细节问题 知识点详解来源 UI资源导入详解 Unity中的UI资源有图片、矢量图、字体、预制体、图集、动画等等资源。 这其中图片是最重要以及最基础的资源组成&a…...
MLX-Audio:高效音频合成的新时代利器
MLX-Audio:高效音频合成的新时代利器 现代社会的快节奏生活中,对语音技术的需求越来越高。无论是个性化语音助手,还是内容创作者所需的高效音频生成工具,语音技术都发挥着不可或缺的作用。今天,我们将介绍一个创新的开…...
操作系统导论——第27章 插叙:线程API
关键问题:如何创建和控制线程? 操作系统应该提供哪些创建和控制线程的接口?这些接口如何设计得易用和实用? 一、线程创建 编写多线程程序的第一步就是创建新线程,因此必须存在某种线程创建接口。在 POSIX 中࿱…...
代采系统:定义、优势与未来趋势
一、代采系统的定义 代采系统是一种基于互联网的集中采购平台,它通过整合供应链资源,为中小企业或个人提供采购代理服务。商家可以在没有自己库存的情况下销售产品,当客户下单时,订单信息会自动或手动发送给供应商,由…...
后缀表达式+栈(详解)(c++)
前言 很抱歉,上一期没有介绍栈stack的用法,今天简要介绍一下,再讲讲后缀表达式,用stack栈做一些后缀表达式的练习。 栈 栈stack是c中系统给出的栈,有了它,就不用自己创建栈啦! 头文件 栈sta…...
Kaggle图像分类竞赛实战总结详细代码解读
前言 我是跟着李沐的动手学深度学习v2视频学习深度学习的,光看不做假把式,所以在学习完第七章-现代卷积神经网络之后,参加了一次李沐发布的Kaggle竞赛。自己动手,从组织数据集开始,到训练,再到推理&#x…...
开源AI对比--dify、n8n
原文网址:开源AI对比--dify、n8n-CSDN博客 简介 本文介绍开源AI工作流工具的选型。 对比 项difyn8n占优者学习难度简单中等dify核心理念用LLM构建应用。“连接一切”。以工作流自动化连接各系统。平手工作模式 Chatflow:对话。支持用户意图识别、上下…...
【SQL系列】多表关联更新
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
软件设计师教程——第一章 计算机系统知识(下)
前言 在竞争激烈的就业市场中,证书是大学生求职的重要加分项。中级软件设计师证书专业性强、认可度高,是计算机相关专业学生考证的热门选择,既能检验专业知识,又有助于职业发展。本教程将聚焦核心重点,以点带面构建知…...
华为银河麒麟 V10(ARM)系统软件部署全攻略:Redis、RabbitMQ、MySQL 等集群搭建指南
一、Redis 集群部署(主从 哨兵模式) 1. 环境准备 系统:华为银河麒麟 V10(ARM64)节点:3 台服务器(1 主 2 从 3 哨兵) 2. 安装包下载 bash # 华为镜像站 wget https://update.c…...
World of Warcraft [CLASSIC][80][Deluyia] [Fragment of Val‘anyr]
瓦兰奈尔的碎片 [Fragment of Valanyr] 有时候下个班打个游戏,没想到套路也这么多,唉,何况现实生活,这一个片版本末期才1000G,30个,也就30000G,时光徽章等同月卡15000G,折合一下也就…...
C++:求分数序列和
【描述】 有一个分数序列 2/1,3/2,5/3,8/5,13/8,21/13,.... 求这个分数序列的前n项之和。 输入 输入有一行:正整数n。 输出 输出有一行:分数序列的和(浮点数,精确到小数点后4位)。 【样例输入】 99 【样例输出】 160.4…...
支付宝沙盒模式商家转账经常出现 响应异常: 解包错误
2025年5月9日16:27:08 php8.3 laravel11 octane swoole加速 测试时不时就出现 响应异常: 解包错误 错误信息: Yansongda\Artful\Exception\InvalidResponseException: 响应异常: 解包错误 in /opt/www/vendor/yansongda/artful/src/Direction/CollectionDirect…...
第04章—技术突击篇:如何根据求职意向进行快速提升与复盘
经过上一讲的内容阐述后,咱们定好了一个与自身最匹配的期望薪资,接着又该如何准备呢? 很多人在准备时,通常会选择背面试八股文,这种做法效率的确很高,毕竟能在“八股文”上出现的题,也绝对是面…...
数据统计的意义:钱包余额变动
钱包余额变动统计的核心意义在于通过数据可视化实现资金流动的透明化管理,其价值主要体现在以下五个维度: 一、财务健康诊断() 资金流动可视化 通过期初/期末余额对比,可快速识别异常波动(如连续3个月余额…...
单调栈模版型题目(3)
单调栈型题目贡献法 基本模版 这是数组a中的 首先我们要明白什么叫做贡献,在一个数组b{1,3,5}中,连续包含1的连续子数组为{1},{1,3},{1,3,5},一共有三个,这三个数一共能组成6个连续子数组,而其…...
PostgreSQL 的 pg_advisory_lock 函数
PostgreSQL 的 pg_advisory_lock 函数 pg_advisory_lock 是 PostgreSQL 提供的一种应用级锁机制,它不锁定具体的数据库对象(如表或行),而是通过数字键值来协调应用间的并发控制。 锁的基本概念 PostgreSQL 提供两种咨询锁(advi…...
NLP基础
1. 基本概念 自然语言处理(Natural Language Processing,简称NLP)是人工智能和语言学领域的一个分支,它涉及到计算机和人类(自然)语言之间的相互作用。它的主要目标是让计算机能够理解、解释和生成人类语言…...
[AI Tools] Dify 工具插件上传指南:如何将插件发布到官方市场
Dify 作为开源的 LLM 应用开发平台,不仅支持本地化插件开发,也提供了插件市场机制,让开发者能够将自己构建的插件发布并供他人使用。本文将详细介绍如何将你开发的 Dify Tools 插件上传至官方插件市场,包括 README 编写、插件打包、仓库 PR 等核心步骤。 一、准备 README 文…...
Qt读写XML文档
XML 结构与概念简介 XML(可扩展标记语言) 是一种用于存储和传输结构化数据的标记语言。其核心特性包括: 1、树状结构:XML 数据以层次化的树形结构组织,包含一个根元素(Root Element)ÿ…...
htmlUnit和Selenium的区别以及使用BrowserMobProxy捕获网络请求
1. Selenium:浏览器自动化之王 核心定位: 跨平台、跨语言的浏览器操控框架,通过驱动真实浏览器实现像素级用户行为模拟。 技术架构: 核心特性: 支持所有主流浏览器(含移动端模拟) 精…...
C#黑魔法:鸭子类型(Duck Typing)
C#黑魔法:鸭子类型(Duck Typing) 如果它走起路来像鸭子,叫起来像鸭子,那么它就是鸭子。 鸭子类型,主要应用于动态语言类型,比如JS、Python等,核心理念为:关注对象的行为(方法或属性…...
2025 年数维杯数学建模B题完整论文代码模型
《2025 年数维杯数学建模B题完整论文代码模型》 B题完整论文 一、赛事背景与题目总览 2025 年第十届数维杯大学生数学建模挑战赛的 B 题聚焦于“马拉松经济的高质量发展思路探索”。近年来,我国马拉松赛事如同一颗颗璀璨的星星,在城市的天空中闪耀&am…...
C++23 中的 views::chunk:深入探索与应用
文章目录 一、views::chunk 的背景与动机二、views::chunk 的基本用法语法与参数示例代码 三、views::chunk 的高级用法处理不完整块与 views::drop 和 views::take 结合 四、性能分析五、应用场景1. 批量处理数据2. 分页显示3. 并行处理 六、与其他范围适配器的组合1. 与 view…...
库室指静脉人脸门禁机 LK-BM-S10C/JR
1、采用大于等于四核处理器,主频大于1G; 2、内存≥4G DDR3;存储≥8G 3、核心模块采用国产工业级处理芯片和嵌入式Android实时多任务系统,采用模块化设计,模块间通过标准接口相连; 4、大于等于10英寸电容屏…...
低成本自动化改造的18个技术锚点深度解析
执行摘要 本文旨在深入剖析四项关键的低成本自动化技术,这些技术为工业转型提供了显著的运营和经济效益。文章将提供实用且深入的指导,涵盖老旧设备联网、AGV车队优化、空压机系统智能能耗管控以及此类项目投资回报率(ROI)的严谨…...
线程中常用的方法
知识点详细说明 Java线程的核心方法集中在Thread类和Object类中,以下是新增整合后的常用方法分类解析: 1. 线程生命周期控制 方法作用注意事项start()启动新线程,JVM调用run()方法多次调用会抛出IllegalThreadStateException(线程状态不可逆)。run()线程的任务逻辑直接调…...
运维体系架构规划
运维体系架构规划是一个系统性工程,旨在构建高效、稳定、安全的运维体系,保障业务系统的持续运行。下面从规划目标、核心模块、实施步骤等方面进行详细阐述: 一、规划目标 高可用性:确保业务系统 724 小时不间断运行,…...
C++结构体介绍
结构体的定义 在C中,结构体(struct)是一种用户定义的数据类型,允许将不同类型的数据组合在一起。结构体的定义使用struct关键字,后跟结构体名称和一对花括号{},花括号内包含成员变量的声明。 struct Pers…...
RoPE长度外推:外插内插
RoPE:假定 α \alpha α是定值 其中一半位置是用cos表示的 cos ( k α − 2 i d ) \cos(k\alpha^{-\frac{2i}{d}}) cos(kα−d2i)(另一半是sin)(d是词嵌入维度) 当太长如何解决: 1 直接不管—外插 缺点:超过一定长度性能急剧下降。(较大时,对应的很多位置编码…...
牛客练习赛138-题解
牛客练习赛138-题解 https://ac.nowcoder.com/acm/contest/109081#question A-小s的签到题 题目描述 给定一个比赛榜单: 第一行是 n 个不同的大写字母,代表题号第二行是 n 个形如a/b的字符串,表示每道题的通过人数和提交人数 找到通过人…...
MySQL高可用方案全攻略:选型指南与AI运维实践
MySQL高可用方案全攻略:选型指南与AI运维实践 引言:当数据库成为业务生命线 在数字化时代,数据库就是企业的"心脏"。一次数据库宕机可能导致: 电商网站每秒损失上万元订单游戏公司遭遇玩家大规模流失金融系统引发连锁反应本文将为你揭秘: MySQL主流高可用方案…...
【库(Library)、包(Package)和模块(Module)解析】
在Python中,**库(Library)、包(Package)和模块(Module)**是代码组织的不同层级,而import语句的导入行为与它们密切相关。以下是详细对比和解释: 📦 1. 核心概…...
记录一次使用thinkphp使用PhpSpreadsheet扩展导出数据,解决身份证号码等信息科学计数法问题处理
PhpSpreadsheet官网 PhpSpreadsheet安装 composer require phpoffice/phpspreadsheet使用composer安装时一定要下载php对应的版本,下载之前使用php -v检查当前php版本 简单使用 <?php require vendor/autoload.php;use PhpOffice\PhpSpreadsheet\Spreadshee…...
为什么业务总是被攻击?使用游戏盾解决方案
业务频繁遭受攻击的核心原因在于攻防资源不对等,攻击者利用技术漏洞、利益驱动及企业防护短板发起攻击,而游戏盾通过针对性架构设计实现高效防御。以下是具体分析与解决方案: 一、业务被攻击的根源 利益驱动攻击 勒索与数…...
4.1【LLaMA-Factory 实战】医疗领域大模型:从数据到部署的全流程实践
【LLaMA-Factory实战】医疗领域大模型:从数据到部署的全流程实践 一、引言 在医疗AI领域,构建专业的疾病诊断助手需要解决数据稀缺、知识专业性强、安全合规等多重挑战。本文基于LLaMA-Factory框架,详细介绍如何从0到1打造一个垂直领域的医…...
二维旋转矩阵:让图形动起来的数学魔法 ✨
大家好!今天我们要聊一个超酷的数学工具——旋转矩阵。它就像数学中的"旋转魔法",能让图形在平面上优雅地转圈圈。别被"矩阵"这个词吓到,其实它就是一个数字表格,但功能超级强大! 一、什么是旋转…...
go语言封装、继承与多态:
1.封装: 封装是通过将数据和操作数据的方法绑定在一起来实现的。在Go语言中,封装通过结构体(struct)和方法(method)来实现。结构体的字段可以通过大小写来控制访问权限。 package stutype Person struct …...
golang -- 如何获取变量类型
目录 前言获取变量类型一、fmt.Printf二、类型断言三、类型选择四、反射 reflect.TypeOf五、reflect.Value的Type()方法 前言 在学习反射的时候,对reflect包中获取变量类型的函数很迷惑 比如下面这个 用Type获取变量类型的方法(在下面提到) …...
Missashe考研日记-day36(改版说明)
Missashe考研日记-day36 改版说明 经过一天的思考、纠结和尝试,博主决定对更新内容进行改版,如下:1.不再每天都发一篇日记,改为一周发一篇包含一周七天学习进度的周记,但为了标题和以前相同(强迫症&#…...