当前位置: 首页 > news >正文

马来西亚网站后缀网页链接成整体通过网站

马来西亚网站后缀,网页链接成整体通过网站,网站建设费用怎么算,宜昌市夷陵区建设局网站前言 关于位置编码和RoPE 我之前在本博客中的另外两篇文章中有阐述过(一篇是关于LLaMA解读的#xff0c;一篇是关于transformer从零实现的)#xff0c;但自觉写的不是特别透彻好懂再后来在我参与主讲的类ChatGPT微调实战课中也有讲过#xff0c;但有些学员依然反馈RoPE不是…前言 关于位置编码和RoPE 我之前在本博客中的另外两篇文章中有阐述过(一篇是关于LLaMA解读的一篇是关于transformer从零实现的)但自觉写的不是特别透彻好懂再后来在我参与主讲的类ChatGPT微调实战课中也有讲过但有些学员依然反馈RoPE不是特别好理解 为彻底解决这个位置编码/RoPE的问题我把另外两篇文章中关于这部分的内容抽取出来并不断深入、扩展、深入最终成为本文 第一部分 transformer原始论文中的标准位置编码 如此篇文章所述RNN的结构包含了序列的时序信息而Transformer却完全把时序信息给丢掉了比如“他欠我100万”和“我欠他100万”两者的意思千差万别故为了解决时序的问题Transformer的作者用了一个绝妙的办法位置编码(Positional Encoding)。 即将每个位置编号从而每个编号对应一个向量最终通过结合位置向量和词向量作为输入embedding就给每个词都引入了一定的位置信息这样Attention就可以分辨出不同位置的词了具体怎么做呢 如果简单粗暴的话直接给每个向量分配一个数字比如1到1000之间也可以用one-hot编码表示位置 transformer论文中作者通过sin函数和cos函数交替来创建 positional encoding其计算positional encoding的公式如下 其中pos相当于是每个token在整个序列中的位置相当于是0, 1, 2, 3...(看序列长度是多大比如10比如100)代表位置向量的维度(也是词embedding的维度transformer论文中设置的512维)  至于是embedding向量的位置下标对2求商并取整(可用双斜杠表示整数除法即求商并取整)它的取值范围是比如 ... 相当于是指向量维度中的偶数维即第0维、第2维、第4维...第510维用sin函数计算 是向量维度中的奇数维即第1维、第3维、第5维..第511维用cos函数计算 不要小看transformer的这个位置编码不少做NLP多年的人也不一定对其中的细节有多深入而网上大部分文章谈到这个位置编码时基本都是千篇一律、泛泛而谈很少有深入故本文还是细致探讨下 考虑到一图胜千言 一例胜万语举个例子当我们要编码「我 爱 你」的位置向量假定每个token都具备512维如果位置下标从0开始时则根据位置编码的计算公式可得『且为让每个读者阅读本文时一目了然我计算了每个单词对应的位置编码示例(在此之前这些示例在其他地方基本没有)』 当对上的单词「我」进行位置编码时它本身的维度有512维当对上的单词「爱」进行位置编码时它本身的维度有512维  然后再叠加上embedding向量可得 当对上的单词「你」进行位置编码时它本身的维度有512维.... 最终得到的可视化效果如下图所示 代码实现如下 “”“位置编码的实现调用父类nn.Module的构造函数”“” class PositionalEncoding(nn.Module):def __init__(self, d_model, dropout, max_len5000):super(PositionalEncoding, self).__init__() self.dropout nn.Dropout(pdropout) # 初始化dropout层# 计算位置编码并将其存储在pe张量中pe torch.zeros(max_len, d_model) # 创建一个max_len x d_model的全零张量position torch.arange(0, max_len).unsqueeze(1) # 生成0到max_len-1的整数序列并添加一个维度# 计算div_term用于缩放不同位置的正弦和余弦函数div_term torch.exp(torch.arange(0, d_model, 2) *-(math.log(10000.0) / d_model))# 使用正弦和余弦函数生成位置编码对于d_model的偶数索引使用正弦函数对于奇数索引使用余弦函数。pe[:, 0::2] torch.sin(position * div_term)pe[:, 1::2] torch.cos(position * div_term)pe pe.unsqueeze(0) # 在第一个维度添加一个维度以便进行批处理self.register_buffer(pe, pe) # 将位置编码张量注册为缓冲区以便在不同设备之间传输模型时保持其状态# 定义前向传播函数def forward(self, x):# 将输入x与对应的位置编码相加x x Variable(self.pe[:, :x.size(1)], requires_gradFalse)# 应用dropout层并返回结果return self.dropout(x) 本文发布之后有同学留言问上面中的第11行、12行代码 div_term torch.exp(torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model)) 为什么先转换为了等价的指数对数运算而不是直接幂运算是效率、精度方面有差异吗 这里使用指数和对数运算的原因是为了确保数值稳定性和计算效率。 一方面直接使用幂运算可能会导致数值上溢或下溢。当d_model较大时10000.0 ** (-i / d_model)中的幂可能会变得非常小以至于在数值计算中产生下溢。通过将其转换为指数和对数运算可以避免这种情况因为这样可以在计算过程中保持更好的数值范围二方面在许多计算设备和库中指数和对数运算的实现通常比幂运算更快。这主要是因为指数和对数运算在底层硬件和软件中有特定的优化实现而幂运算通常需要计算更多的中间值 所以使用指数和对数运算可以在保持数值稳定性的同时提高计算效率。 既然提到了这行代码我们干脆就再讲更细致些上面那行代码对应的公式为 其中的中括号对应的是一个从 0 到 的等差数列(步长为 2)设为 且上述公式与这个公式是等价的 为何原因在于从而有 最终再通过下面这两行代码完美实现位置编码 # 使用正弦和余弦函数生成位置编码对于d_model的偶数索引使用正弦函数对于奇数索引使用余弦函数。pe[:, 0::2] torch.sin(position * div_term)pe[:, 1::2] torch.cos(position * div_term) 第二部分 如何彻底理解旋转位置嵌入(RoPE) 在位置编码上删除了绝对位置嵌入而在网络的每一层增加了苏剑林等人(2021)提出的旋转位置嵌入(RoPE)其思想是采用绝对位置编码的形式 实现相对位置编码且RoPE主要借助了复数的思想 先复习下复数的一些关键概念 我们一般用表示复数实数a叫做复数的实部实数b叫做复数的虚部复数的辐角是指复数在复平面上对应的向量和正向实数轴所成的有向角 的共轭复数定义为也可记作复数与其共轭的乘积等于它的模的平方即这是一个实数 2.1 旋转位置编码的原理 当咱们给self-attention中的向量都加入了位置信息后便可以表示为 其中 表示第  个 token 对应的词向量  集成位置信息  之后的 query 向量而 和  则表示第  个 token 对应的词向量  集成位置信息  之后的 key 和 value 向量 2.1.1 第一种形式的推导 接着论文中提出为了能利用上 token 之间的相对位置信息假定 query 向量  和 key 向量  之间的内积操作可以被一个函数  表示该函数  的输入是词嵌入向量 、 它们之间的相对位置  假定现在词嵌入向量的维度是两维  这样就可以利用上2维度平面上的向量的几何性质然后论文中提出了一个满足上述关系的  和  的形式如下 这里面 Re 表示复数的实部。 进一步地 可以表示成下面的式子 看到这里会发现这不就是 query 向量乘以了一个旋转矩阵吗这就是为什么叫做旋转位置编码的原因 同理  可以表示成下面的式子 最终可以表示如下 上述三个式子咋一步一步推导来的 // 待更亲们莫急23年10月底更好.. 2.1.2 第二种形式的推导 与上面第一种形式的推导类似为了引入复数首先假设了在加入位置信息之前原有的编码向量是二维行向量和其中和是绝对位置现在需要构造一个变换将和引入到和中即寻找变换  也就是说我们分别为、设计操作、使得经过该操作后、就带有了位置、的绝对位置信息 考虑到Attention的核心计算是内积 故我们希望的内积的结果带有相对位置信息即寻求的这个变换应该具有特性 「怎么理解很简单当m和n表示了绝对位置之后m与n在句子中的距离即位置差m-n就可以表示为相对位置了且对于复数内积通常定义为一个复数与另一个复数的共轭的乘积」 为合理的求出该恒等式的一个尽可能简单的解可以设定一些初始条件比如、然后可以先考虑二维情形然后借助复数来求解 在复数中有表示取实部的操作(复数 和“ 复数 的共轭即 ”之积仍是一个复数)总之我们需要寻找一种变换使得简单起见我们假设存在复数使得然后我们用复数的指数形式设那么代入方程后就得到两个方程 方程1 方程2Θf(q,m)−Θf(k,n) Θg(q,k,m−n)  对于方程1代入得到(接着再把和都设为0) 最后一个等号源于初始条件和所以现在我们可以很简单地设即它不依赖于  至于方程2同样代入得到 Θf(q,m)−Θf(k,m) Θg(q,k,0) Θf(q,0)−Θf(k,0) Θ(q)−Θ(k) 这里的、是、本身的幅角而最后一个等号同样源于初始条件 根据上式Θf(q,m)−Θf(k,m) Θ(q)−Θ(k)可得Θf(q,m)−Θ(q)Θf(k,m)−Θ(k)所以Θf(q,m)−Θ(q)的结果是一个只与m相关、跟q无关的函数记为φ(m)即Θf(q,m)Θ(q)φ(m)接着令nm−1代入Θf(q,m)−Θf(k,n) Θg(q,k,m−n)可以得到 Θf(q,m)−Θf(k,m-1) Θg(q,k,1) 然后将 Θf(q,m) 和 Θf(k,m-1) 的等式代入Θf(q,m)Θ(q)φ(m)我们可以得到 Θ(q) φ(m) - (Θ(k) φ(m-1)) Θg(q,k,1)整理一下就得到 即{φ(m)}是等差数列设右端为θ那么就解得φ(m)mθ 综上我们得到二维情况下用复数表示的RoPE所以说寻求的变换就是也就是给乘以相应地乘以 做了这样一个变换之后根据复数的特性有 也就是如果把二维向量看做复数那么它们的内积等于一个复数乘以另一个复数的共轭得到的结果再取实部代入上面的变换也就有 这样一来内积的结果就只依赖于也就是相对位置了 换言之经过这样一番操作通过给Embedding添加绝对位置信息可以使得两个token的编码经过内积变换self-attn之后得到结果是受它们位置的差值即相对位置影响的 于是对于任意的位置为的二维向量把它看做复数乘以而根据欧拉公式有 从而上述的相乘变换也就变成了(过程中注意) 把上述式子写成矩阵形式 而这个变换的几何意义就是在二维坐标系下对向量进行了旋转因而这种位置编码方法被称为旋转位置编码 根据刚才的结论结合内积的线性叠加性可以将结论推广到高维的情形。可以理解为每两个维度一组进行了上述的“旋转”操作然后再拼接在一起 由于矩阵的稀疏性会造成计算上的浪费所以在计算时采用逐位相乘再相加的方式进行 其中为矩阵逐位相乘操作 2.2 旋转位置编码的coding实现(分非LLaMA版和LLaMA版两种) 原理理解了接下来可以代码实现旋转位置编码考虑到LLaMA本身的实现不是特别好理解所以我们先通过一份非LLaMA实现的版本最后再看下LLaMA实现的版本 对于非LLaMA版的实现其核心就是实现下面这三个函数 (再次强调本份关于RoPE的非LLaMA版的实现 与上面和之后的代码并非一体的仅为方便理解RoPE的实现) 2.2.1 非LLaMA版的实现 2.2.1.1 sinusoidal_position_embedding的编码实现 sinusoidal_position_embedding这个函数用来生成正弦形状的位置编码。这种编码用来在序列中的令牌中添加关于相对或绝对位置的信息 def sinusoidal_position_embedding(batch_size, nums_head, max_len, output_dim, device):# (max_len, 1)position torch.arange(0, max_len, dtypetorch.float).unsqueeze(-1)# (output_dim//2)# 即公式里的i, i的范围是 [0,d/2]ids torch.arange(0, output_dim // 2, dtypetorch.float) theta torch.pow(10000, -2 * ids / output_dim)# (max_len, output_dim//2)# 即公式里的pos / (10000^(2i/d))embeddings position * theta # (max_len, output_dim//2, 2)embeddings torch.stack([torch.sin(embeddings), torch.cos(embeddings)], dim-1)# (bs, head, max_len, output_dim//2, 2)# 在bs维度重复其他维度都是1不重复embeddings embeddings.repeat((batch_size, nums_head, *([1] * len(embeddings.shape)))) # (bs, head, max_len, output_dim)# reshape后就是偶数sin, 奇数cos了embeddings torch.reshape(embeddings, (batch_size, nums_head, max_len, output_dim))embeddings embeddings.to(device)return embeddings 一般的文章可能解释道这个程度基本就over了但为了让初学者一目了然计我还是再通过一个完整的示例来一步步说明上述各个步骤都是怎么逐一结算的整个过程和之前此文里介绍过的transformer的位置编码本质上是一回事.. 为方便和transformer的位置编码做对比故这里也假定output_dim 512 首先我们有 ids 张量当 output_dim 为 512 时则 ... ids [0,0, 1,1, 2,2, ..., 254,254, 255,255] 然后我们有一个基数为10000的指数运算使用了公式 torch.pow(10000, -2 * ids / output_dim) 执行 embeddings position * theta 这行代码它会将 position 的每个元素与 theta 的相应元素相乘前三个元素为接下来我们将对 embeddings 的每个元素应用 torch.sin 和 torch.cos 函数 对于 torch.sin(embeddings)我们将取 embeddings 中的每个元素的正弦值 对于 torch.cos(embeddings)我们将取 embeddings 中的每个元素的余弦值 最后torch.stack([torch.sin(embeddings), torch.cos(embeddings)], dim-1) 将这两个新的张量沿着一个新的维度堆叠起来得到的 embeddings如下 最终得到如下结果 [[[[sin(\frac{0}{10000^{\frac{0}{512}}}), cos(\frac{0}{10000^{\frac{0}{512}}}), sin(\frac{0}{10000^{\frac{2}{512}}}), cos(\frac{0}{10000^{\frac{2}{512}}}), ..., cos(\frac{0}{10000^{\frac{510}{512}}})],[sin(\frac{1}{10000^{\frac{0}{512}}}), cos(\frac{1}{10000^{\frac{0}{512}}}), sin(\frac{1}{10000^{\frac{2}{512}}}), cos(\frac{1}{10000^{\frac{2}{512}}}), ..., cos(\frac{1}{10000^{\frac{510}{512}}})],[sin(\frac{2}{10000^{\frac{0}{512}}}), cos(\frac{2}{10000^{\frac{0}{512}}}), sin(\frac{2}{10000^{\frac{2}{512}}}), cos(\frac{2}{10000^{\frac{2}{512}}}), ..., cos(\frac{2}{10000^{\frac{510}{512}}})]]] ] 2.2.2.2 RoPE的编码实现 RoPE这个函数将相对位置编码RoPE应用到注意力机制中的查询和键上。这样模型就可以根据相对位置关注不同的位置 import torch import torch.nn as nn import torch.nn.functional as F import mathdef RoPE(q, k):# q,k: (bs, head, max_len, output_dim)batch_size q.shape[0]nums_head q.shape[1]max_len q.shape[2]output_dim q.shape[-1]# (bs, head, max_len, output_dim)pos_emb sinusoidal_position_embedding(batch_size, nums_head, max_len, output_dim, q.device)# cos_pos,sin_pos: (bs, head, max_len, output_dim)# 看rope公式可知相邻cossin之间是相同的所以复制一遍。如(1,2,3)变成(1,1,2,2,3,3)cos_pos pos_emb[..., 1::2].repeat_interleave(2, dim-1) # 将奇数列信息抽取出来也就是cos 拿出来并复制sin_pos pos_emb[..., ::2].repeat_interleave(2, dim-1) # 将偶数列信息抽取出来也就是sin 拿出来并复制# q,k: (bs, head, max_len, output_dim)q2 torch.stack([-q[..., 1::2], q[..., ::2]], dim-1)q2 q2.reshape(q.shape) # reshape后就是正负交替了# 更新qw, *对应位置相乘q q * cos_pos q2 * sin_posk2 torch.stack([-k[..., 1::2], k[..., ::2]], dim-1)k2 k2.reshape(k.shape)# 更新kw, *对应位置相乘k k * cos_pos k2 * sin_posreturn q, k 老规矩为一目了然起见还是一步一步通过一个示例来加深理解 sinusoidal_position_embedding函数生成位置嵌入。在output_dim512的情况下每个位置的嵌入会有512个维度但为了简单起见我们只考虑前8个维度前4个维度为sin编码后4个维度为cos编码。所以我们可能得到类似以下的位置嵌入 # 注意这只是一个简化的例子真实的位置嵌入的值会有所不同。 pos_emb torch.tensor([[[[0.0000, 0.8415, 0.9093, 0.1411, 1.0000, 0.5403, -0.4161, -0.9900],[0.8415, 0.5403, 0.1411, -0.7568, 0.5403, -0.8415, -0.9900, -0.6536],[0.9093, -0.4161, -0.8415, -0.9589, -0.4161, -0.9093, -0.6536, 0.2836]]]]) 然后我们提取出所有的sin位置编码和cos位置编码并在最后一个维度上每个位置编码进行复制 sin_pos pos_emb[..., ::2].repeat_interleave(2, dim-1) # 提取出所有sin编码并在最后一个维度上复制 cos_pos pos_emb[..., 1::2].repeat_interleave(2, dim-1) # 提取出所有cos编码并在最后一个维度上复制 更新query向量 我们首先构建一个新的q2向量这个向量是由原来向量的负的cos部分和sin部分交替拼接而成的 我们用cos_pos对q进行元素级乘法用sin_pos对q2进行元素级乘法并将两者相加得到新的query向量 q2 torch.stack([-q[..., 1::2], q[..., ::2]], dim-1).flatten(start_dim-2) # q2: tensor([[[[-0.2, 0.1, -0.4, 0.3, -0.6, 0.5, -0.8, 0.7], # [-1.0, 0.9, -1.2, 1.1, -1.4, 1.3, -1.6, 1.5], # [-1.8, 1.7, -2.0, 1.9, -2.2, 2.1, -2.4, 2.3]]]])q q * cos_pos q2 * sin_pos 公式表示如下 ​​​​​更新key向量 对于key向量我们的处理方法与query向量类似 k2 torch.stack([-k[..., 1::2], k[..., ::2]], dim-1).flatten(start_dim-2) # k2: tensor([[[[-0.15, 0.05, -0.35, 0.25, -0.55, 0.45, -0.75, 0.65 2.2.2.3 attention的编码实现 attention这是注意力机制的主要功能 首先如果use_RoPE被设置为True它会应用RoPE通过取查询和键的点积并进行缩放然后进行softmax操作来计算注意力分数以得到概率输出是值的加权和权重是计算出的概率最后旋转后的q和k计算点积注意力后自然就具备了相对位置信息 def attention(q, k, v, maskNone, dropoutNone, use_RoPETrue):# q.shape: (bs, head, seq_len, dk)# k.shape: (bs, head, seq_len, dk)# v.shape: (bs, head, seq_len, dk)if use_RoPE:# 使用RoPE进行位置编码q, k RoPE(q, k)d_k k.size()[-1]# 计算注意力权重# (bs, head, seq_len, seq_len)att_logits torch.matmul(q, k.transpose(-2, -1)) att_logits / math.sqrt(d_k)if mask is not None:# 对权重进行mask将为0的部分设为负无穷大att_scores att_logits.masked_fill(mask 0, -1e-9) # 对权重进行softmax归一化# (bs, head, seq_len, seq_len)att_scores F.softmax(att_logits, dim-1) if dropout is not None:# 对权重进行dropoutatt_scores dropout(att_scores)# 注意力权重与值的加权求和# (bs, head, seq_len, seq_len) * (bs, head, seq_len, dk) (bs, head, seq_len, dk)return torch.matmul(att_scores, v), att_scoresif __name__ __main__:# (bs, head, seq_len, dk)q torch.randn((8, 12, 10, 32))k torch.randn((8, 12, 10, 32))v torch.randn((8, 12, 10, 32))# 进行注意力计算res, att_scores attention(q, k, v, maskNone, dropoutNone, use_RoPETrue)# 输出结果的形状# (bs, head, seq_len, dk), (bs, head, seq_len, seq_len)print(res.shape, att_scores.shape) 2.2.2 LLaMA版的实现 接下来我们再来看下LLaMA里是怎么实现这个旋转位置编码的具体而言LLaMA 的model.py文件里面实现了旋转位置编码(为方便大家理解我给相关代码 加了下注释) 首先逐一实现这三个函数 precompute_freqs_cis reshape_for_broadcast apply_rotary_emb # 预计算频率和复数的函数 def precompute_freqs_cis(dim: int, end: int, theta: float 10000.0):freqs 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))    # 计算频率t torch.arange(end, devicefreqs.device)    # 根据结束位置生成序列freqs torch.outer(t, freqs).float()    # 计算外积得到新的频率freqs_cis torch.polar(torch.ones_like(freqs), freqs)    # 计算复数return freqs_cis    # 返回复数 # 重塑的函数 def reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor):ndim x.ndim    # 获取输入张量的维度assert 0 1 ndim    # 检查维度的合理性assert freqs_cis.shape (x.shape[1], x.shape[-1])    # 检查复数的形状shape [d if i 1 or i ndim - 1 else 1 for i, d in enumerate(x.shape)]    # 计算新的形状return freqs_cis.view(*shape)    # 重塑复数的形状并返回 # 应用旋转嵌入的函数 def apply_rotary_emb(xq: torch.Tensor,xk: torch.Tensor,freqs_cis: torch.Tensor, ) - Tuple[torch.Tensor, torch.Tensor]:xq_ torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2))    # 将xq视为复数xk_ torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2))    # 将xk视为复数freqs_cis reshape_for_broadcast(freqs_cis, xq_)    # 重塑复数的形状xq_out torch.view_as_real(xq_ * freqs_cis).flatten(3)    # 计算xq的输出xk_out torch.view_as_real(xk_ * freqs_cis).flatten(3)    # 计算xk的输出return xq_out.type_as(xq), xk_out.type_as(xk)    # 返回xq和xk的输出 之后在注意力机制的前向传播函数中调用上面实现的第三个函数 apply_rotary_emb赋上位置信息 (详见下文1.2.5节) # 对Query和Key应用旋转嵌入xq, xk apply_rotary_emb(xq, xk, freqs_cisfreqs_cis)
文章转载自:
http://www.morning.wspjn.cn.gov.cn.wspjn.cn
http://www.morning.gwgjl.cn.gov.cn.gwgjl.cn
http://www.morning.gkjnz.cn.gov.cn.gkjnz.cn
http://www.morning.dmzfz.cn.gov.cn.dmzfz.cn
http://www.morning.njnqn.cn.gov.cn.njnqn.cn
http://www.morning.wfwqr.cn.gov.cn.wfwqr.cn
http://www.morning.zljqb.cn.gov.cn.zljqb.cn
http://www.morning.tmxfn.cn.gov.cn.tmxfn.cn
http://www.morning.pbsqr.cn.gov.cn.pbsqr.cn
http://www.morning.trnl.cn.gov.cn.trnl.cn
http://www.morning.kztpn.cn.gov.cn.kztpn.cn
http://www.morning.mingjiangds.com.gov.cn.mingjiangds.com
http://www.morning.rggky.cn.gov.cn.rggky.cn
http://www.morning.kszkm.cn.gov.cn.kszkm.cn
http://www.morning.cptzd.cn.gov.cn.cptzd.cn
http://www.morning.ccyjt.cn.gov.cn.ccyjt.cn
http://www.morning.flqbg.cn.gov.cn.flqbg.cn
http://www.morning.pangucheng.cn.gov.cn.pangucheng.cn
http://www.morning.hsjrk.cn.gov.cn.hsjrk.cn
http://www.morning.c7513.cn.gov.cn.c7513.cn
http://www.morning.xkgyh.cn.gov.cn.xkgyh.cn
http://www.morning.080203.cn.gov.cn.080203.cn
http://www.morning.ffcsr.cn.gov.cn.ffcsr.cn
http://www.morning.vuref.cn.gov.cn.vuref.cn
http://www.morning.lffbz.cn.gov.cn.lffbz.cn
http://www.morning.bpmdq.cn.gov.cn.bpmdq.cn
http://www.morning.mbzlg.cn.gov.cn.mbzlg.cn
http://www.morning.qmwzr.cn.gov.cn.qmwzr.cn
http://www.morning.gfqj.cn.gov.cn.gfqj.cn
http://www.morning.cyysq.cn.gov.cn.cyysq.cn
http://www.morning.qqrlz.cn.gov.cn.qqrlz.cn
http://www.morning.ffrys.cn.gov.cn.ffrys.cn
http://www.morning.nmkfy.cn.gov.cn.nmkfy.cn
http://www.morning.lffgs.cn.gov.cn.lffgs.cn
http://www.morning.lpcpb.cn.gov.cn.lpcpb.cn
http://www.morning.lmdkn.cn.gov.cn.lmdkn.cn
http://www.morning.nxtgb.cn.gov.cn.nxtgb.cn
http://www.morning.jyfrz.cn.gov.cn.jyfrz.cn
http://www.morning.kzrbn.cn.gov.cn.kzrbn.cn
http://www.morning.jmbfx.cn.gov.cn.jmbfx.cn
http://www.morning.gxcym.cn.gov.cn.gxcym.cn
http://www.morning.nrzkg.cn.gov.cn.nrzkg.cn
http://www.morning.hqpyt.cn.gov.cn.hqpyt.cn
http://www.morning.hhfwj.cn.gov.cn.hhfwj.cn
http://www.morning.gxfpk.cn.gov.cn.gxfpk.cn
http://www.morning.cwjsz.cn.gov.cn.cwjsz.cn
http://www.morning.glxmf.cn.gov.cn.glxmf.cn
http://www.morning.zxqyd.cn.gov.cn.zxqyd.cn
http://www.morning.tmcmj.cn.gov.cn.tmcmj.cn
http://www.morning.pqnpd.cn.gov.cn.pqnpd.cn
http://www.morning.qpqwd.cn.gov.cn.qpqwd.cn
http://www.morning.smrkf.cn.gov.cn.smrkf.cn
http://www.morning.ktpzb.cn.gov.cn.ktpzb.cn
http://www.morning.mhbcy.cn.gov.cn.mhbcy.cn
http://www.morning.fsjcn.cn.gov.cn.fsjcn.cn
http://www.morning.mxnhq.cn.gov.cn.mxnhq.cn
http://www.morning.rfmzs.cn.gov.cn.rfmzs.cn
http://www.morning.brwwr.cn.gov.cn.brwwr.cn
http://www.morning.rcwbc.cn.gov.cn.rcwbc.cn
http://www.morning.gqhgl.cn.gov.cn.gqhgl.cn
http://www.morning.yrhd.cn.gov.cn.yrhd.cn
http://www.morning.bzlfw.cn.gov.cn.bzlfw.cn
http://www.morning.bwdnx.cn.gov.cn.bwdnx.cn
http://www.morning.cpmwg.cn.gov.cn.cpmwg.cn
http://www.morning.yxplz.cn.gov.cn.yxplz.cn
http://www.morning.txlnd.cn.gov.cn.txlnd.cn
http://www.morning.kfstq.cn.gov.cn.kfstq.cn
http://www.morning.fthcq.cn.gov.cn.fthcq.cn
http://www.morning.xdmsq.cn.gov.cn.xdmsq.cn
http://www.morning.bsjxh.cn.gov.cn.bsjxh.cn
http://www.morning.nynlf.cn.gov.cn.nynlf.cn
http://www.morning.yjmlg.cn.gov.cn.yjmlg.cn
http://www.morning.xhqr.cn.gov.cn.xhqr.cn
http://www.morning.hypng.cn.gov.cn.hypng.cn
http://www.morning.fwgnq.cn.gov.cn.fwgnq.cn
http://www.morning.pszw.cn.gov.cn.pszw.cn
http://www.morning.mtmnk.cn.gov.cn.mtmnk.cn
http://www.morning.mkxxk.cn.gov.cn.mkxxk.cn
http://www.morning.wyzby.cn.gov.cn.wyzby.cn
http://www.morning.xglgm.cn.gov.cn.xglgm.cn
http://www.tj-hxxt.cn/news/261389.html

相关文章:

  • 哪建网站好同一虚拟空间做两个网站
  • 湛江海田网站建设招聘设计网页多少钱
  • 东营建设信息网网站深圳做夜场做网站
  • 设计个网站需要怎么做做外贸一般用什么网站好
  • 301网站重定向怎么做工信部 网站 邮箱
  • 网站排名效果好龙口网页设计
  • raid管理网站开发电商app系统开发公司
  • 免费行情网站app下载大全南昌网站排名优化价格
  • 网站建设流程机构深圳宝安房价
  • 网站推广互联网推广网站关键词做排名不分
  • 后期网站郑州网站营销推广公司
  • 查公司的网站有哪些有网站是做水果原产地代发的吗
  • 关于课题网站建设的协议wordpress显示加载耗时
  • 网站建设中字样图片广州app开发外包
  • 爱站网长尾词挖掘工具建设公司logo图片大全
  • 南京怎样做网站山东省建设文化传媒有限公司网站
  • 网站云空间和普通空间网络结构分几层
  • 商丘做网站汉狮网络网站运营包括哪些内容
  • 大屏手机网站wordpress 热门标签
  • 山西电商网站开发炉石卡牌制作网页
  • 中国美院网站建设公司windows10网站建设
  • 烟台网站title优化给别人做网站要问什么问题
  • 优秀网站h5案例分享网站自动收录
  • 做网站需要什么技术员百度站内搜索提升关键词排名
  • 关键词与网站标题网站权重值在较长时间内是一定的页面优化
  • 义县城乡建设局网站福州网站设计哪里建站
  • 海尔电子商务网站建设电子版简历免费的
  • 免费公网网站建设上海cms模板建站
  • 中小企业网站制作公司电子项目外包网站
  • wordpress可以制作什么网站吗有哪些可以做h5的网站