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

上海品划网站建设有限公司做网站需要解析吗

上海品划网站建设有限公司,做网站需要解析吗,wordpress建立的网站,wordpress 盒模型大学引言 自然语言处理 (NLP) 领域的进展日新月异#xff0c;你方唱罢我登场。因此#xff0c;在实际场景中#xff0c;针对特定的任务#xff0c;我们经常需要对不同的语言模型进行比较#xff0c;以寻找最适合的模型。本文主要比较 3 个模型: RoBERTa、Mistral-7B 及 Llama-… 引言 自然语言处理 (NLP) 领域的进展日新月异你方唱罢我登场。因此在实际场景中针对特定的任务我们经常需要对不同的语言模型进行比较以寻找最适合的模型。本文主要比较 3 个模型: RoBERTa、Mistral-7B 及 Llama-2-7B。我们用它们来解决一个常见问题 —— 对灾难相关的推文进行分类。值得注意的是Mistral 和 Llama 2 是 70 亿参数的大模型。相形之下RoBERTa-large (355M 参数) 只是一个小模型我们用它作为比较的基线。 本文我们使用 PEFT (Parameter-Efficient Fine-Tuning参数高效微调) 技术: LoRA (Low-Rank Adaptation低秩适配) 来微调带序列分类任务头的预训练模型。LoRA 旨在显著减少可训参数量同时保持强大的下游任务性能。 本文的主要目标是通过对 Hugging Face 的三个预训练模型进行 LoRA 微调使之适用于序列分类任务。这三个预训练模型分别是: meta-llama/Llama-2-7b-hf、mistralai/Mistral-7B-v0.1 及 roberta-large。 使用的硬件 节点数: 1每个节点的 GPU 数: 1GPU 类型: A6000GPU 显存: 48GB 目标 使用 LoRA PEFT 方法对预训练 LLM 进行微调。了解如何使用 Hugging Face 的各种 API (transformers、peft 以及 datasets)。使用 Weights Biases 进行超参调优以及实验日志记录。 软件依赖 datasets evaluate peft scikit-learn torch transformers wandb 注意: 要准确重现本文结果请注意确保软件版本与 wandb 报告 的一致。 预训练模型 RoBERTa RoBERTa (Robustly Optimized BERT Approach) 是 Meta AI 研究团队提出的改进版 BERT 模型。BERT 是一种基于 transformer 的语言模型其基于自注意力机制对单词进行上下文感知的表征并基于掩码语言模型目标进行训练。请注意BERT 作为编码器模型仅可用于自然语言理解任务 (例如序列分类和词元分类)。 RoBERTa 是一种流行的可微调模型很适合作为我们实验的基线。欲了解更多信息你可以查阅其 Hugging Face 模型卡。 Llama 2 Llama 2 (Large Language Model Meta AI) 是 Meta AI 推出的一系列大语言模型 (LLM)其模型大小各异参数量从 70 亿到 650 亿不等。 Llama 2 是一种基于 transformer 解码器架构的自回归语言模型。Llama 2 接受单词序列作为输入并基于滑动窗口迭代预测下一个词元从而实现文本生成的功能。 Llama 2 的架构与 GPT-3 等模型略有不同。举几个例子Llama 2 采用 SwiGLU 激活函数而不是 ReLU另外其位置嵌入使用的是旋转位置嵌入而不是可训绝对位置嵌入。 最近发布的 Llama 2 还对架构进行了改进其将支持的最大上下文长度扩展到 4096 个词元并使用分组查询注意 (grouped-query attentionGQA) 解码机制来更好地利用长序列。 Mistral 7B Mistral 7B v0.1 有 73 亿个参数是 Mistral AI 推出的第一个 LLM。 Mistral 7B 架构使用的新技术主要有: 滑窗注意力: 用基于滑动窗口的注意力替换完整注意力 (平方级计算成本)其中每个词元最多可以关注上一层的 4096 个词元 (线性计算成本)。这样多层以后Mistral 7B 的实际关注词元数会叠加因此更高层的注意力实际关注的总历史词元数会超过 4096。分组查询注意力: Llama 2 也使用了该技术其通过缓存先前解码的词元的键向量和值向量来优化推理过程 (减少处理时间)。 LoRA PEFT (Parameter Efficient Fine-Tuning参数高效微调) 包含 p-tuning、前缀微调 (prefix-tuning) 、IA3、适配器微调以及 LoRA 等一系列技术其旨在通过仅微调大模型的一个小参数集就能达到全模型微调的性能水平。 LoRA (Low-Rank Adaptation低阶适配) 的方法与添加适配层类似。其主要目标是减少模型的可训参数量。LoRA 的主要做法是冻结预训练权重仅更新一个新增的低秩矩阵。 环境设置 RoBERTa 支持的最大序列长度为 512为公平起见对所有模型我们统一设定 MAX_LEN512 。 MAX_LEN  512 roberta_checkpoint  roberta-large mistral_checkpoint  mistralai/Mistral-7B-v0.1 llama_checkpoint  meta-llama/Llama-2-7b-hf 数据准备 数据加载 从 Hugging Face 加载数据集: from datasets import load_dataset dataset  load_dataset(mehdiiraqui/twitter_disaster) 将数据集分为训练集和验证集同时加载测试集: from datasets import Dataset # 将数据集的训练集划分为训练集和验证集 data  dataset[train].train_test_split(train_size0.8, seed42) # 把划分而得的测试集重命名为验证集 data[val]  data.pop(test) # 将原数据集的测试集仍作为测试集 data[test]  dataset[test] 以下是数据集概览: DatasetDict({train: Dataset({features: [id, keyword, location, text, target],num_rows: 6090})val: Dataset({features: [id, keyword, location, text, target],num_rows: 1523})test: Dataset({features: [id, keyword, location, text, target],num_rows: 3263}) }) 首先检查一下数据分布: import pandas as pddata[train].to_pandas().info() data[test].to_pandas().info() 训练集 RangeIndex: 7613 entries, 0 to 7612 Data columns (total 5 columns):# Column Non-Null Count Dtype --- ------ -------------- -----0 id 7613 non-null int641 keyword 7552 non-null object2 location 5080 non-null object3 text 7613 non-null object4 target 7613 non-null int64 dtypes: int64(2), object(3) memory usage: 297.5 KB 测试集 class pandas.core.frame.DataFrame RangeIndex: 3263 entries, 0 to 3262 Data columns (total 5 columns):# Column Non-Null Count Dtype --- ------ -------------- -----0 id 3263 non-null int641 keyword 3237 non-null object2 location 2158 non-null object3 text 3263 non-null object4 target 3263 non-null int64 dtypes: int64(2), object(3) memory usage: 127.6 KB 训练集中标签分布情况: target 0 4342 1 3271 Name: count, dtype: int64 由于类别不平衡我们计算一下正负类权重以用于稍后的损失计算: pos_weights  len(data[train].to_pandas()) / (2 * data[train].to_pandas().target.value_counts()[1]) neg_weights  len(data[train].to_pandas()) / (2 * data[train].to_pandas().target.value_counts()[0]) 计算出的权重为: POS_WEIGHT, NEG_WEIGHT  (1.1637114032405993, 0.8766697374481806) 接着我们计算文本序列的最大长度: # 字符数 max_char  data[train].to_pandas()[text].str.len().max() # 词数 max_words  data[train].to_pandas()[text].str.split().str.len().max() The maximum number of characters is 152. The maximum number of words is 31. 数据处理 以一条训练数据为例: data[train][0] {id: 5285,keyword: fear,location: Thibodaux, LA,text: my worst fear. https://t.co/iH8UDz8mq3,target: 0} 该数据中包括关键字、位置和推文。为了简单起见我们选择 text 特征作为 LLM 的唯一输入。 本阶段的目标是为 LLM 微调准备所需的 Hugging Face 格式的训练集、验证集和测试集。然后是定义用于训练的词元数据集使用合适的分词器将 text 特征转换为词元 id 和注意力掩码序列这两个张量。由于每个模型都有其特定的分词器因此我们需要生成三个不同的数据集每个模型一个。 我们首先定义 RoBERTa 模型的数据加载器: 加载与分词: from transformers import AutoTokenizer roberta_tokenizer  AutoTokenizer.from_pretrained(roberta_checkpoint, add_prefix_spaceTrue) 注意: RoBERTa 分词器经过训练已将空格视为词元的一部分。因此如果句子的第一个单词前面没有空格则其编码会有所不同。为了确保第一个单词包含空格我们设置 add_prefix_spaceTrue 。同时为了保持三个模型的预处理一致我们将 Llama 2 和 Mistral 7B 的相应参数也设为 True 。 定义每条数据的预处理函数: def roberta_preprocessing_function(examples):return roberta_tokenizer(examples[text], truncationTrue, max_lengthMAX_LEN) 将预处理函数应用于训练数据集的第一条数据我们得到了分词后的输入 ( input_ids ) 及其注意力掩码: roberta_preprocessing_function(data[train][0]) {input_ids: [0, 127, 2373, 2490, 4, 1205, 640, 90, 4, 876, 73, 118, 725, 398, 13083, 329, 398, 119, 1343, 246, 2], attention_mask: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]} 现在将预处理函数应用于整个数据集: col_to_delete  [id, keyword,location, text] # 删除不需要的列并应用预处理函数 roberta_tokenized_datasets  data.map(roberta_preprocessing_function, batchedTrue, remove_columnscol_to_delete) # 按照 HuggingFace 的要求将 target 列  重命名为 label 列 roberta_tokenized_datasets  roberta_tokenized_datasets.rename_column(target, label) # 数据集格式设为 torch roberta_tokenized_datasets.set_format(torch) 注意: 我们从数据中删除了不需要的列: id 、 keyword 、 location 及 text 。删除 text 的原因是我们已经将其转换为输入 id 和注意力掩码: 分词后的训练数据集中的数据如下: roberta_tokenized_datasets[train][0] {label: tensor(0),input_ids: tensor([ 0, 127, 2373, 2490, 4, 1205, 640, 90, 4, 876,73, 118, 725, 398, 13083, 329, 398, 119, 1343, 246,2]),attention_mask: tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])} 为了生成训练 batch 数据我们还需要对给定 batch 中的序列进行填充以使 batch 中所有序列的长度都等于本 batch 最长序列的长度。为此我们使用了 DataCollatorWithPadding 类: # 数据整理器将所有数据统一填充至 batch 内最长序列的长度 from transformers import DataCollatorWithPadding roberta_data_collator  DataCollatorWithPadding(tokenizerroberta_tokenizer) 用相同的流程为 Mistral 7B 和 Llama 2 模型准备数据: 注意 Llama 2 和 Mistral 7B 没有默认的 pad_token_id 我们将其设为 eos_token_id 。 Mistral 7B: # 加载 Mistral 7B 分词器 from transformers import AutoTokenizer, DataCollatorWithPadding mistral_tokenizer  AutoTokenizer.from_pretrained(mistral_checkpoint, add_prefix_spaceTrue) mistral_tokenizer.pad_token_id  mistral_tokenizer.eos_token_id mistral_tokenizer.pad_token  mistral_tokenizer.eos_tokendef mistral_preprocessing_function(examples):return mistral_tokenizer(examples[text], truncationTrue, max_lengthMAX_LEN)mistral_tokenized_datasets  data.map(mistral_preprocessing_function, batchedTrue, remove_columnscol_to_delete) mistral_tokenized_datasets  mistral_tokenized_datasets.rename_column(target, label) mistral_tokenized_datasets.set_format(torch)# 序列填充 mistral_data_collator  DataCollatorWithPadding(tokenizermistral_tokenizer) Llama 2: # 加载 Llama 2 分词器 from transformers import AutoTokenizer, DataCollatorWithPadding llama_tokenizer  AutoTokenizer.from_pretrained(llama_checkpoint, add_prefix_spaceTrue) llama_tokenizer.pad_token_id  llama_tokenizer.eos_token_id llama_tokenizer.pad_token  llama_tokenizer.eos_tokendef llama_preprocessing_function(examples):return llama_tokenizer(examples[text], truncationTrue, max_lengthMAX_LEN)llama_tokenized_datasets  data.map(llama_preprocessing_function, batchedTrue, remove_columnscol_to_delete) llama_tokenized_datasets  llama_tokenized_datasets.rename_column(target, label) llama_tokenized_datasets.set_format(torch)# 序列填充 llama_data_collator  DataCollatorWithPadding(tokenizerllama_tokenizer) 至此我们已经准备好了分词后的数据集下一节我们将讨论如何加载预训练 LLM 检查点以及如何设置 LoRA 权重。 模型 RoBERTa 为分类任务加载 RoBERTa 检查点 我们使用 Hugging Face AutoModelForSequenceClassification 类加载带有序列分类头的预训练 RoBERTa 模型: from transformers import AutoModelForSequenceClassification roberta_model  AutoModelForSequenceClassification.from_pretrained(roberta_checkpoint, num_labels2) RoBERTa 分类器的 LoRA 设置 我们为 RoBERTa 分类器设置 LoRA 参数: TaskType: 序列分类r(rank): 分解矩阵的秩lora_alpha: 用于对习得权重进行缩放的 alpha 参数。LoRA 论文建议将 alpha 固定为 16lora_dropout: LoRA 层的 Dropout 概率bias: 是否向 LoRA 层添加偏置 以下代码使用了 LoRA 论文 的推荐设置。后文 我们还将用 wandb 对这些超参进行调优。 from peft import get_peft_model, LoraConfig, TaskType roberta_peft_config  LoraConfig(task_typeTaskType.SEQ_CLS, r2, lora_alpha16, lora_dropout0.1, biasnone, ) roberta_model  get_peft_model(roberta_model, roberta_peft_config) roberta_model.print_trainable_parameters() 可以看到可训参数量仅占 RoBERTa 模型参数量的 0.64%: trainable params: 2,299,908 || all params: 356,610,052 || trainable%: 0.6449363911929212 Mistral 为分类任务加载检查点 加载带有序列分类头的预训练 Mistral-7B 模型: from transformers import AutoModelForSequenceClassification import torch mistral_model   AutoModelForSequenceClassification.from_pretrained(pretrained_model_name_or_pathmistral_checkpoint,num_labels2,device_mapauto ) 设置填充词元 id因为 Mistral 7B 没有默认填充词元。 mistral_model.config.pad_token_id  mistral_model.config.eos_token_id Mistral 7B 分类器的 LoRA 设置 对 Mistral 7B 模型而言我们需要指定 target_modules (我们将其指定为注意力模块的查询向量映射层和值向量映射层): from peft import get_peft_model, LoraConfig, TaskTypemistral_peft_config  LoraConfig(task_typeTaskType.SEQ_CLS, r2, lora_alpha16, lora_dropout0.1, biasnone,target_modules[q_proj,v_proj,], )mistral_model  get_peft_model(mistral_model, mistral_peft_config) mistral_model.print_trainable_parameters() 可训参数量仅占 Mistral 模型参数量的 0.024%: trainable params: 1,720,320 || all params: 7,112,380,416 || trainable%: 0.02418768259540745 Llama 2 为分类任务加载检查点 加载带有序列分类头的预训练 Llama 2 模型。 from transformers import AutoModelForSequenceClassification import torch llama_model   AutoModelForSequenceClassification.from_pretrained(pretrained_model_name_or_pathllama_checkpoint,num_labels2,device_mapauto,offload_folderoffload,trust_remote_codeTrue ) 设置填充词元 id因为 Llama 2 没有默认填充词元。 llama_model.config.pad_token_id  llama_model.config.eos_token_id Llama 2 分类器的 LoRA 设置 使用与 Mistral 相同的 LoRA 参数: from peft import get_peft_model, LoraConfig, TaskType llama_peft_config  LoraConfig(task_typeTaskType.SEQ_CLS, r16, lora_alpha16, lora_dropout0.05, biasnone,target_modules[q_proj,v_proj,], )llama_model  get_peft_model(llama_model, llama_peft_config) llama_model.print_trainable_parameters() 可训参数量仅占 Llama 2 模型参数量的 0.12%: trainable params: 8,404,992 || all params: 6,615,748,608 || trainable%: 0.1270452143516515 至此我们定义了用于训练的词元数据集及 LoRA 设置。下面我们介绍如何使用 Hugging Face 的 Trainer 类启动训练。 设置 Trainer 评估指标 首先我们定义用于对三个模型的性能进行比较的指标: F1 分数、召回率、精确度和准确度: import evaluate import numpy as npdef compute_metrics(eval_pred):# HF evaluate 包已支持我们所要的所有指标precision_metric  evaluate.load(precision)recall_metric  evaluate.load(recall)f1_metric evaluate.load(f1)accuracy_metric  evaluate.load(accuracy)logits, labels  eval_pred# eval_pred 是模型返回的预测值和实际值元组predictions  np.argmax(logits, axis-1)precision  precision_metric.compute(predictionspredictions, referenceslabels)[precision]recall  recall_metric.compute(predictionspredictions, referenceslabels)[recall]f1  f1_metric.compute(predictionspredictions, referenceslabels)[f1]accuracy  accuracy_metric.compute(predictionspredictions, referenceslabels)[accuracy]# Trainer 要求将指标组织为一个字典其键为指标名值为分数。return {precision: precision, recall: recall, f1-score: f1, accuracy: accuracy} 基于加权损失的自定义 Trainer 前文提到数据集正负类分布并不平衡。因此我们用加权交叉熵损失来训练模型以解决这个问题。Trainer 类本身的实现中不支持自定义损失因为它期望直接从模型的输出中获取损失。 因此我们需要定义一个自定义的 WeightedCELossTrainer 以重写 compute_loss 方法该方法可以根据模型的预测和标签计算加权交叉熵损失: from transformers import Trainerclass WeightedCELossTrainer(Trainer):def compute_loss(self, model, inputs, return_outputsFalse):labels  inputs.pop(labels)# Get models predictionsoutputs  model(**inputs)logits  outputs.get(logits)# Compute custom lossloss_fct  torch.nn.CrossEntropyLoss(weighttorch.tensor([neg_weights, pos_weights], devicemodel.device, dtypelogits.dtype))loss  loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))return (loss, outputs) if return_outputs else loss Trainer 设置 我们为三个模型分别设置训练超参及训练器。 RoBERTa 第一步把模型搬到 GPU 设备上。 roberta_model  roberta_model.cuda() roberta_model.device() It will print the following: device(typecuda, index0) 然后设置训练超参: from transformers import TrainingArgumentslr  1e-4 batch_size  8 num_epochs  5training_args  TrainingArguments(output_dirroberta-large-lora-token-classification,learning_ratelr,lr_scheduler_type constant,warmup_ratio 0.1,max_grad_norm 0.3,per_device_train_batch_sizebatch_size,per_device_eval_batch_sizebatch_size,num_train_epochsnum_epochs,weight_decay0.001,evaluation_strategyepoch,save_strategyepoch,load_best_model_at_endTrue,report_towandb,fp16False,gradient_checkpointingTrue, ) 最后我们将模型、训练超参和词元数据集一起作为参数来实例化一个 RoBERTa 训练器: roberta_trainer  WeightedCELossTrainer(modelroberta_model,argstraining_args,train_datasetroberta_tokenized_datasets[train],eval_datasetroberta_tokenized_datasets[val],data_collatorroberta_data_collator,compute_metricscompute_metrics ) Mistral-7B 与 RoBERTa 类似我们用如下代码初始化 WeightedCELossTrainer : from transformers import TrainingArguments, Trainermistral_model  mistral_model.cuda()lr  1e-4 batch_size  8 num_epochs  5training_args  TrainingArguments(output_dirmistral-lora-token-classification,learning_ratelr,lr_scheduler_type constant,warmup_ratio 0.1,max_grad_norm 0.3,per_device_train_batch_sizebatch_size,per_device_eval_batch_sizebatch_size,num_train_epochsnum_epochs,weight_decay0.001,evaluation_strategyepoch,save_strategyepoch,load_best_model_at_endTrue,report_towandb,fp16True,gradient_checkpointingTrue, )mistral_trainer  WeightedCELossTrainer(modelmistral_model,argstraining_args,train_datasetmistral_tokenized_datasets[train],eval_datasetmistral_tokenized_datasets[val],data_collatormistral_data_collator,compute_metricscompute_metrics ) 注意我们需要将 fp16 设为 True 以启用半精度训练。主要原因是 Mistral-7B 很大如果使用 fp32 精度其权重无法放进单块 GPU 的显存 (48GB) 中。 Llama 2 与 Mistral 7B 类似我们用如下代码定义训练器: from transformers import TrainingArguments, Trainerllama_model  llama_model.cuda()lr  1e-4 batch_size  8 num_epochs  5 training_args  TrainingArguments(output_dirllama-lora-token-classification,learning_ratelr,lr_scheduler_type constant,warmup_ratio 0.1,max_grad_norm 0.3,per_device_train_batch_sizebatch_size,per_device_eval_batch_sizebatch_size,num_train_epochsnum_epochs,weight_decay0.001,evaluation_strategyepoch,save_strategyepoch,load_best_model_at_endTrue,report_towandb,fp16True,gradient_checkpointingTrue, )llama_trainer  WeightedCELossTrainer(modelllama_model,argstraining_args,train_datasetllama_tokenized_datasets[train],eval_datasetllama_tokenized_datasets[val],data_collatorllama_data_collator,compute_metricscompute_metrics ) 超参调优 我们用 Wandb Sweep API 通过贝叶斯搜索策略来进行超参调优 (30 次运行)待调优的超参搜索空间如下: 方法指标lora_alphalora_biaslora_dropoutlora_ranklrmax_lengthbayes目标: maximize分布: categorical分布: categorical分布: uniform分布: categorical分布: uniform分布: categorical目标名: eval/f1-score取值集合: -16     -32     -64取值集合: None-最大值: 0.1   -最小值: 0取值集合:      -4   -8    -16     -32-最大值: 2e-04-最小值: 1e-05取值集合: 512 欲了解更多信息可以查看 资源 一节中的 Wandb 实验报告。 结果 模型F1 分数训练时间内存消耗可训参数量RoBERTa0.8077538 秒GPU1: 9.1 GBGPU2: 8.3 GB0.64%Mistral 7B0.73642030 秒GPU1: 29.6 GbGPU2: 29.5 GB0.024%Llama 20.76382052 秒GPU1: 35 GB GPU2: 33.9 GB0.12% 总结 本文我们用 LoRA 对三个大语言模型 (LLM) (RoBERTa、Mistral 7B 及 Llama 2) 针对灾难推文分类任务进行微调。从性能结果来看RoBERTa 的性能大幅优于 Mistral 7B 和 Llama 2。这就提出了一个问题: 我们是否真的需要一个大而复杂的 LLM 来完成诸如短序列二分类这样的简单任务 一个重要的启示是在选择要使用的 LLM 模型时应该考虑具体的项目要求、可用资源和性能需求。 此外对于针对短序列的相对 简单 的预测任务小的基础模型 (例如 RoBERTa) 仍然具有竞争力。 最后我们还通过例子展示了 LoRA 方法的通用性其既可应用于编码器 (RoBERTa) 模型还可应用于解码器 (Llama 2 及 Mistral 7B) 模型。 资源 本文代码均已在该 Github 项目。下面是各模型的 Wandb 超参调优实验报告: RoBERTaMistral 7BLlama 2 宝子们可以戳 阅读原文 查看文中所有的外部链接哟 英文原文: https://hf.co/blog/Lora-for-sequence-classification-with-Roberta-Llama-Mistral 原文作者: Mehdi Iraqi 译者: Matrix Yao (姚伟峰)英特尔深度学习工程师工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。
http://www.zqtcl.cn/news/590710/

相关文章:

  • 知名建站的公司微信企业app手机下载安装
  • 鹤山做网站羊毛网站建设视频
  • 图书类网站开发的背景建筑培训机构
  • 外贸网站建设制作wordpress管理员页面404
  • 北郊网站建设app网站开发哪里有
  • 像素人物制作网站网站开发的话术
  • 网站关键词怎么优化排名wordpress电子商城模板
  • 电子商务网站建设与维护能赚多少钱成交型网站建设
  • 到国外做网站网站是怎么回事中国一级建造师网官网
  • 惠州网站建设哪家好网站对图片优化
  • 酒店网站建设报价详情wordpress表单留言
  • 58同城做公司网站怎修改在线葡京在线葡京
  • 家纺网站模板wordpress折叠菜单
  • 建设信用中国网站站群系统破解版
  • 百度怎么投放广告凡科网站可以做seo优化
  • 医院网站建设 不足好的手机网站建设公司
  • 简历上作品展示网站链接怎么做wordpress的登陆地址修改密码
  • 深圳做响应式网站公司公司网站开发费用放在什么科目
  • 网站页面上的悬浮窗怎么做简单好看的版面设计图
  • 我要在58上面做网站硬件开发和嵌入式的区别
  • 西安网站推广慧创新手怎么开网店
  • 做羞羞事视频网站网站策划书基本项目
  • 对网站建设的维护优秀设计网站推荐
  • 口红机网站怎么做wordpress 搭建个人网站
  • 黄金网站房地产网站建设意义
  • 百度网站联盟公司做网站计入那个科目
  • 越秀电子商务网站建设国外的ui设计思想网站
  • 网站关键词优化公司网站建设完成确认书
  • 企业微信网站怎么建设山东有哪些网络公司
  • 做任务领佣金的网站源码页面设计参评