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

网站颜色正确搭配实例wordpress页面文章

网站颜色正确搭配实例,wordpress页面文章,招平面设计师的招聘信息,响应式网站设计布局1. 引言 分词器是每个大语言模型必不可少的组件#xff0c;但每个大语言模型的分词器几乎都不相同。如果要训练自己的分词器#xff0c;可以使用huggingface的tokenizers框架#xff0c;tokenizers包含以下主要组件#xff1a; Tokenizer: 分词器的核心组件#xff0c;定…1. 引言 分词器是每个大语言模型必不可少的组件但每个大语言模型的分词器几乎都不相同。如果要训练自己的分词器可以使用huggingface的tokenizers框架tokenizers包含以下主要组件 Tokenizer: 分词器的核心组件定义了分词的整个流程包括标准化、预分词、模型分词、后处理等Normalizers可选负责将文本标准化包括unicode归一化、大写转小写、去重音等操作Pre-tokenizers负责将文本分割成更小的片段如单词等为模型分词做准备。常见的预分词器有按空格分词Whitespace、正则表达式分词Regex等Models是实际的分词算法负责将文本片段转换为子词常见的有BPE、WordPiece、Unigram等。Post-Processors负责对分词结果进行后处理如添加特殊标记CLS、SEP。Decoders负责将分词结果转换回原始文本常见的解码器有 ByteLevel、WordPiece 等。Trainers用于训练分词模型不同的模型对应不同的训练器如 BpeTrainer、WordPieceTrainer、UnigramTrainer 等。 在开始之前先导入对应的包。 import json import re import os from tokenizers import (decoders,models,normalizers,pre_tokenizers,processors,trainers,Tokenizer, )2. 加载语料库 我们准备好的语料库是一个jsonl文件大概有736MB每一行是一条json格式的文本数据既有中文也有英文。 !ls -n /data2/minigpt/dataset/tokenize/tokenizer_train.jsonl-rw-rw-r-- 1 736729803 Nov 4 22:04 /data2/minigpt/dataset/tokenize/tokenizer_train.jsonl定义一个函数用于从JSONL文件中读取文本数据考虑到语料库会比较大所以采用yield生成器来延迟到访问时再加载数据。 def read_texts_from_jsonl(file_path):with open(file_path, r, encodingutf-8) as f:for i, line in enumerate(f):data json.loads(line)yield data[text] data_path /data2/minigpt/dataset/tokenize/tokenizer_train.jsonl texts read_texts_from_jsonl(data_path) type(texts)generator可以看到函数read_texts_from_jsonl返回的并不是真正的数据而是一个生成器generator。可以通过next函数像访问iterator一样访问迭代数据。 next(texts)好的。现在请你将这个文本中的所有的逗号都替换成空格。 好的请稍等一下现在我会将文本中的所有逗号替换为空格。处理后文本为这是一个句子 目的是看看是否可以正确地从这个句子中删除关键词。。处理结果如何3. 训练过程 3.1 模型选择 使用BPE模型来初始化Tokenizer实例。 tokenizer Tokenizer(models.BPE())BPE是一种基于子词的分词方法例如 cats - cat shelpful - help fulcongratulation - con gr at ulation 这种基于子词的分词方法相比基于完整单词和基于单个字符有以下好处 子词相比于单词可以认为多个子词的组合数量要可控这能避免词表过大并且能避免生僻词带来的未知令牌问题。子词相比于字符语义性更强像单个字符f是没有语义的但子词ful可以表达满的比较像英语里的词根词缀。 3.2 预分词器选择 为tokenizer设置预分词器预分词器有以下几类 Whitespace按空格分隔粒度为单词适用于空格分隔的语言例如英语。Regex按自定义正则表达式分隔适用于需要自定义复杂分词规则的场景。ByteLevel按字节分割适用于特殊字符、非英语场景例如中文。 由于我们主要面向中文所以这里采用ByteLevel的pre_tokenizer。 tokenizer.pre_tokenizer pre_tokenizers.ByteLevel(add_prefix_spaceFalse) tokenizer.pre_tokenizertokenizers.pre_tokenizers.ByteLevel at 0x7f41641266f0预分词器的方法列表 dir(tokenizer.pre_tokenizer)[……add_prefix_space,alphabet,custom,pre_tokenize,pre_tokenize_str,use_regex]那pre_tokenizer具体对文本作了什么处理呢可以通过下面两个例子来观察下。 测试英文文本处理。 tokenizer.pre_tokenizer.pre_tokenize_str(Pre-tokenize a :class:~tokenizers.PyPreTokenizedString in-place)[(Pre, (0, 3)),(-, (3, 4)),(tokenize, (4, 12)),(Ġa, (12, 14)),(Ġ:, (14, 16)),(class, (16, 21)),(:~, (21, 24)),(tokenizers, (24, 34)),(., (34, 35)),(PyPreTokenizedString, (35, 55)),(, (55, 56)),(Ġin, (56, 59)),(-, (59, 60)),(place, (60, 65))]可以看到pre_tokenizer将文本按照空格和特殊字符作了初步分词空格处理成了特殊字符Ġ并记录了每个词的起始和结束位置。 测试中文文本处理。 zh_sentence 在查处虚开增值税专用发票案件中常常涉及进项留抵税额和税款损失的认定和处理。 tokenizer.pre_tokenizer.pre_tokenize_str(zh_sentence)[(åľ¨æŁ¥å¤ĦèĻļå¼Ģå¢ŀå̼ç¨İä¸ĵç͍åıij票æ¡Īä»¶ä¸Ń, (0, 15)),(ï¼Į, (15, 16)),(常常æ¶īåıĬè¿Ľé¡¹çķĻæĬµç¨İé¢ĿåĴĮç¨İ款æįŁå¤±çļĦ认å®ļåĴĮå¤ĦçIJĨ, (16, 37)),(ãĢĤ, (37, 38))]中文基本也是按照特殊符号和。进行了分词但分词的结果是一堆不认识的字符这些字符是如何产生的呢 3.3 预分词原理探究 预分词常常使用类似下面一样的正则表达式先对文本进行分隔。 import regex as rePRETOKENIZE_REGEX r(?i:s|t|re|ve|m|ll|d)|[^\r\n\p{L}\p{N}\p{P}]?\p{L}|\p{N}| ?[^\s\p{L}\p{N}][\r\n]*|\s*[\r\n]|\s(?!\S)|\s pat re.compile(PRETOKENIZE_REGEX) tokens re.findall(pat, zh_sentence) tokens[在查处虚开增值税专用发票案件中, , 常常涉及进项留抵税额和税款损失的认定和处理, 。]其中各部分正则表达式的作用如下 (?i:s|t|re|ve|m|ll|d): 匹配常见的英文缩略形式例如sis 或 hastnotrearevehavemamllwilldwould 或 had。[^\r\n\p{L}\p{N}\p{P}]?\p{L}匹配一个或多个 Unicode 字母\p{L}这里的unicode字母包括英文、中文、拉丁等所有语言中的字母允许前面有一个非换行符\r\n、非字母\p{L}、非数字\p{N}和非标点\p{P}的字符相当于是匹配空格、制表符等空白字符。\p{N}匹配任何 Unicode 数字字符。?[^\s\p{L}\p{N}][\r\n]*匹配非空白、非字母、非数字的字符允许前面有一个空格后面跟随换行符相当于是匹配标点符号后面跟换行符。\p{L}匹配任何 Unicode 字母字符包括拉丁字母、希腊字母、汉字等所有语言中的字母。\p{N}匹配任何 Unicode 数字字符涵盖阿拉伯数字、罗马数字等所有形式的数字字符。\p{P}匹配任何 Unicode 标点字符涵盖句号、逗号、引号、括号等所有形式、所有语言中的标点符号。 对于英文以外的其它语言例如中文需要进行utf-8编码将字符编码为字节。 utf-8编码的目的是解决英文、中文、日文、俄文等多语言的问题因为世界上所有语言的字符都可以用一个或多个utf-8字节的组合来表示。 tokens_utf8 [token.encode(utf-8) for token in tokens] tokens_utf8[b\xe5\x9c\xa8\xe6\x9f\xa5\xe5\xa4\x84\xe8\x99\x9a\xe5\xbc\x80\xe5\xa2\x9e\xe5\x80\xbc\xe7\xa8\x8e\xe4\xb8\x93\xe7\x94\xa8\xe5\x8f\x91\xe7\xa5\xa8\xe6\xa1\x88\xe4\xbb\xb6\xe4\xb8\xad,b\xef\xbc\x8c,b\xe5\xb8\xb8\xe5\xb8\xb8\xe6\xb6\x89\xe5\x8f\x8a\xe8\xbf\x9b\xe9\xa1\xb9\xe7\x95\x99\xe6\x8a\xb5\xe7\xa8\x8e\xe9\xa2\x9d\xe5\x92\x8c\xe7\xa8\x8e\xe6\xac\xbe\xe6\x8d\x9f\xe5\xa4\xb1\xe7\x9a\x84\xe8\xae\xa4\xe5\xae\x9a\xe5\x92\x8c\xe5\xa4\x84\xe7\x90\x86,b\xe3\x80\x82]但有个问题是Ascii码中是会包含回车、制表、换行等控制字符的同样utf-8编码中也会有。而我们最终构造的词表必须是可显示的文本所以还要做一个工作是把控制字符都转换为可显示字符为此需要制作一个unicode字节编码表用于将单字节256以内都编码为可显示字符。 0-255范围内的可显示字符分为三段 从 !ASCII 33到 ~ASCII 126。从 ¡Unicode 161到 ¬Unicode 172。从 ®Unicode 174到 ÿUnicode 255。 这三段以外的ASCII码均无法正常显示需要用可显示字符来填充替代。 def bytes_to_unicode():# 收集0-255范围内的可显示字符对应的数字值ord函数用于将字符编码为数字bs (list(range(ord(!), ord(~) 1)) list(range(ord(¡), ord(¬) 1)) list(range(ord(®), ord(ÿ) 1)))cs bs[:]n 0# 补充0-255范围内不可显示字符对应的数字并转换为256以上可显示字符对应的数字值for b in range(2**8):if b not in bs:bs.append(b)cs.append(2**8 n)n 1# chr函数用于将数字转换回unicode字符并创建一个字节值到字符值的映射表。cs [chr(n) for n in cs]return dict(zip(bs, cs))byte_encoder bytes_to_unicode() json.dumps(byte_encoder, ensure_asciiFalse){33: !, 34: \\, 35: #, 36: $, 37: %, 38: , 39: \, 40: (, 41: ), 42: *, 43: , 44: ,, 45: -, 46: ., 47: /, 48: 0, 49: 1, 50: 2, 51: 3, 52: 4, 53: 5, 54: 6, 55: 7, 56: 8, 57: 9, 58: :, 59: ;, 60: , 61: , 62: , 63: ?, 64: , 65: A, 66: B, 67: C, 68: D, 69: E, 70: F, 71: G, 72: H, 73: I, 74: J, 75: K, 76: L, 77: M, 78: N, 79: O, 80: P, 81: Q, 82: R, 83: S, 84: T, 85: U, 86: V, 87: W, 88: X, 89: Y, 90: Z, 91: [, 92: \\\\, 93: ], 94: ^, 95: _, 96: , 97: a, 98: b, 99: c, 100: d, 101: e, 102: f, 103: g, 104: h, 105: i, 106: j, 107: k, 108: l, 109: m, 110: n, 111: o, 112: p, 113: q, 114: r, 115: s, 116: t, 117: u, 118: v, 119: w, 120: x, 121: y, 122: z, 123: {, 124: |, 125: }, 126: ~, 161: ¡, 162: ¢, 163: £, 164: ¤, 165: ¥, 166: ¦, 167: §, 168: ¨, 169: ©, 170: ª, 171: «, 172: ¬, 174: ®, 175: ¯, 176: °, 177: ±, 178: ², 179: ³, 180: ´, 181: µ, 182: ¶, 183: ·, 184: ¸, 185: ¹, 186: º, 187: », 188: ¼, 189: ½, 190: ¾, 191: ¿, 192: À, 193: Á, 194: Â, 195: Ã, 196: Ä, 197: Å, 198: Æ, 199: Ç, 200: È, 201: É, 202: Ê, 203: Ë, 204: Ì, 205: Í, 206: Î, 207: Ï, 208: Ð, 209: Ñ, 210: Ò, 211: Ó, 212: Ô, 213: Õ, 214: Ö, 215: ×, 216: Ø, 217: Ù, 218: Ú, 219: Û, 220: Ü, 221: Ý, 222: Þ, 223: ß, 224: à, 225: á, 226: â, 227: ã, 228: ä, 229: å, 230: æ, 231: ç, 232: è, 233: é, 234: ê, 235: ë, 236: ì, 237: í, 238: î, 239: ï, 240: ð, 241: ñ, 242: ò, 243: ó, 244: ô, 245: õ, 246: ö, 247: ÷, 248: ø, 249: ù, 250: ú, 251: û, 252: ü, 253: ý, 254: þ, 255: ÿ, 0: Ā, 1: ā, 2: Ă, 3: ă, 4: Ą, 5: ą, 6: Ć, 7: ć, 8: Ĉ, 9: ĉ, 10: Ċ, 11: ċ, 12: Č, 13: č, 14: Ď, 15: ď, 16: Đ, 17: đ, 18: Ē, 19: ē, 20: Ĕ, 21: ĕ, 22: Ė, 23: ė, 24: Ę, 25: ę, 26: Ě, 27: ě, 28: Ĝ, 29: ĝ, 30: Ğ, 31: ğ, 32: Ġ, 127: ġ, 128: Ģ, 129: ģ, 130: Ĥ, 131: ĥ, 132: Ħ, 133: ħ, 134: Ĩ, 135: ĩ, 136: Ī, 137: ī, 138: Ĭ, 139: ĭ, 140: Į, 141: į, 142: İ, 143: ı, 144: IJ, 145: ij, 146: Ĵ, 147: ĵ, 148: Ķ, 149: ķ, 150: ĸ, 151: Ĺ, 152: ĺ, 153: Ļ, 154: ļ, 155: Ľ, 156: ľ, 157: Ŀ, 158: ŀ, 159: Ł, 160: ł, 173: Ń}这样每个字节值都从 Unicode 表的开头获得一个分配给它的可见字符。这一点非常重要因为每个utf-8字符都是由一到多个字节组成的将这个长度为256的编码表中的字节进行组合理论上就能对世界上所有语言中的字符进行编码并且还不会出现未知标记。 使用这个unicode字节编码表将前面utf-8编码后的文本序列进行ByteLevel级的编码。 tokens_unicode [.join(byte_encoder[b] for b in token) for token in tokens_utf8] tokens_unicode[åľ¨æŁ¥å¤ĦèĻļå¼Ģå¢ŀå̼ç¨İä¸ĵç͍åıij票æ¡Īä»¶ä¸Ń,ï¼Į,常常æ¶īåıĬè¿Ľé¡¹çķĻæĬµç¨İé¢ĿåĴĮç¨İ款æįŁå¤±çļĦ认å®ļåĴĮå¤ĦçIJĨ,ãĢĤ]可以看到结果与使用pre_tokenizer预分词的结果完全相同。 3.4 构建训练器 BPE训练器中需要指定几个参数 vocab_size训练后词表中的词条数量BPE是一个从短词到长词的组合过程达到词表大小后就会停止训练。special_tokens特殊token和语言模型的特殊token相同例如开始、结束、填充标记。initial_alphabet初始字符表使用上面长度为256的unicode字节编码表作为初始字符表。 通过pre_tokenizers.ByteLevel.alphabet()可以获得初始字符编码表。 json.dumps(pre_tokenizers.ByteLevel.alphabet(), ensure_asciiFalse)[ø, \\\\, ľ, v, ć, ¬, ł, °, ġ, ķ, ĕ, », ], Q, ģ, G, ñ, ¶, é, H, 9, ), ×, Í, Ó, º, £, ~, Ā, s, Ô, 2, Ý, í, â, ·, Ą, ý, ĭ, ², 4, Ù, ĺ, ă, ĸ, Ī, z, K, IJ, N, Ø, 1, n, b, ó, ¼, õ, V, Ö, 6, ©, ė, O, đ, j, h, İ, į, ¨, ¯, Ğ, I, 0, Ă, , ß, Û, Ć, Å, ĩ, Ê, B, ª, W, _, S, Ĥ, Ł, q, ë, Ķ, Ò, Ĉ, Ċ, L, «, U, #, ļ, Ė, å, ´, Î, M, , D, ¤, ô, ç, Y, R, ð, Ĺ, ij, , Ŀ, ę, d, É, à, ŀ, , Ĩ, ¹, Ã, /, ¸, Ģ, X, ê, u, ğ, m, w, Ì, ¢, Æ, C, t, Ļ, ì, ě, Ď, l, ē, Ħ, Ñ, 3, ÷, {, $, y, Ç, ¡, Ë, ĉ, ĵ, Ĵ, Č, a, T, ;, Ń, Ú, f, §, Z, , \, Ä, A, ÿ, Ę, Õ, Ġ, c, %, Ē, ï, ī, Ĕ, ?, (, Đ, Ï, ö, ^, P, ±, x, ,, i, æ, ®, -, ³, î, *, û, ú, ¾, ä, Į, 5, ò, Ĭ, Â, þ, J, ċ, :, ü, ¥, , è, È, ĝ, ą, }, !, r, Þ, g, \\, [, À, ā, ď, 7, ¿, ħ, F, ı, Á, á, Ð, ., , E, č, ½, e, ã, ù, Ľ, Ĝ, ĥ, ¦, Ě, p, Ü, 8, |, k, o, µ]定义特殊token分别为填充、开始、结束标记。 special_tokens [|endoftext|, |im_start|, |im_end|]构建训练器词条数量设置为32000。 trainer trainers.BpeTrainer(vocab_size32000,special_tokensspecial_tokens, # 确保这三个token被包含show_progressTrue,initial_alphabetpre_tokenizers.ByteLevel.alphabet() )使用上面的texts生成器作为语料库使用trainer开始训练分词器。 tokenizer.train_from_iterator(texts, trainertrainer)注这个训练过程的用时长短与文本数据大小有关我们前面加载的文本数据有700多MB, 大概需要十几分钟。 3.5 保存训练结果 在保存结果之前需要先设置相匹配的解码器否则ASCII以外的字符可能无法正常解码。 上面编码阶段使用了ByteLevel的预分词器相对应的解码阶段也需要使用ByteLevel表示将token id转换为token后还需要进行一次unicode字节级别的解码才能正常显示中文等多语言字符。 tokenizer.decoder decoders.ByteLevel()将训练的分词器保存到指定目录。 tokenizer_dir /data2/minigpt/models/tokenizer_v3 os.makedirs(tokenizer_dir, exist_okTrue) tokenizer.save(os.path.join(tokenizer_dir, tokenizer.json)) tokenizer.model.save(tokenizer_dir)[/data2/minigpt/models/tokenizer_v3/vocab.json,/data2/minigpt/models/tokenizer_v3/merges.txt]还需要一个分词器配置文件包括模型类型、是否使用小写字母等。 config {add_bos_token: False,add_eos_token: False,add_prefix_space: True,added_tokens_decoder: {0: {content: |endoftext|,lstrip: False,normalized: False,rstrip: False,single_word: False,special: True},1: {content: |im_start|,lstrip: False,normalized: False,rstrip: False,single_word: False,special: True},2: {content: |im_end|,lstrip: False,normalized: False,rstrip: False,single_word: False,special: True}},additional_special_tokens: [],bos_token: |im_start|,clean_up_tokenization_spaces: False,eos_token: |im_end|,legacy: True,model_max_length: 1000000000000000019884624838656,pad_token: None,sp_model_kwargs: {},spaces_between_special_tokens: False,tokenizer_class: PreTrainedTokenizerFast,unk_token: |endoftext|,use_default_system_prompt: False,chat_template: {% if messages[0][role] system %}{% set system_message messages[0][content] %}{% endif %}{% if system_message is defined %}{{ system_message }}{% endif %}{% for message in messages %}{% set content message[content] %}{% if message[role] user %}{{ |im_start|user\\n content |im_end|\\n|im_start|assistant\\n }}{% elif message[role] assistant %}{{ content |im_end| \\n }}{% endif %}{% endfor %} }保存分词器配置 with open(os.path.join(tokenizer_dir, tokenizer_config.json), w, encodingutf-8) as config_file:json.dump(config, config_file, ensure_asciiFalse, indent4)print(Tokenizer training completed and saved.)Tokenizer training completed and saved.查看磁盘上的词表文件。 !ls -l /data2/minigpt/models/tokenizer_v3total 2548 -rw-rw-r-- 1 golfxiao golfxiao 407951 Oct 10 21:45 merges.txt -rw-rw-r-- 1 golfxiao golfxiao 1686 Oct 10 21:45 tokenizer_config.json -rw-rw-r-- 1 golfxiao golfxiao 1572840 Oct 10 21:45 tokenizer.json -rw-rw-r-- 1 golfxiao golfxiao 621912 Oct 10 21:45 vocab.jsonvocab.json词汇表文件包含词条和对应的索引。merges.txt: 合并表文件定义了子词的合并规则。tokenizer.json: 完整的分词器文件它包含了分词器的所有信息包括词汇表、合并规则、特殊标记等。tokenizer_config.json: 分词器配置文件包括了起始token、结束token的定义以及提示词模板。 4. 测试分词器 from transformers import AutoTokenizer# 加载刚训练的tokenizer tokenizer_dir /data2/minigpt/models/tokenizer_v3 tokenizer_trained AutoTokenizer.from_pretrained(tokenizer_dir)4.1 英文文本测试 先测试英文文本的分词。 text_en Pre-tokenize a :class:~tokenizers.PyPreTokenizedString in-place tokenized tokenizer_trained.tokenize(text_en) tokenized[Pre,-,token,ize,Ġa,Ġ:,class,:,,~,token,izers,.,Py,Pre,T,oken,ized,String,,Ġin,-,place]tokenize方法只负责分词就是将一串文本切分为token列表。我们在给模型输入时一般需要的是token_id这时就需要使用encode方法同时完成token切分和文本到数字的序列化。 token_ids_en tokenizer_trained.encode(text_en) token_ids_en[19714,15,24535,1038,260,6938,9939,28,66,96,24535,11344,16,22966,19714,54,9071,1228,13863,66,295,15,2383]对上面的token_id进行反序列化以测试解码功能。 tokenizer_trained.decode(token_ids_en)Pre-tokenize a :class:~tokenizers.PyPreTokenizedString in-place可以看到解码的结果与原始英文串完全相同。 4.2 中文文本测试 下面测试下中文文本的序列化和反序列化。 text_zh 在查处虚开增值税专用发票案件中常常涉及进项留抵税额和税款损失的认定和处理。 token_ids_zh tokenizer_trained.encode(text_zh) token_ids_zh[368,1698,1319,4304,953,30571,2147,411,646,3917,6723,413,270,6679,4743,631,1467,3692,9083,3534,2676,315,3534,1805,8576,269,1374,627,12769,286]tokenizer_trained.decode(token_ids_zh)在查处虚开增值税专用发票案件中常常涉及进项留抵税额和税款损失的认定和处理。我们刚训练的分词器在中文和英文上都能正常进行的文本的序列化和反序列化操作。 小结本文借助huggingface提供的tokenizers框架以一个真实的语料库为案例演示了分词器训练的过程并最终得到了一个切实可用的分词器。但tokenizers框架封装的比较多所以在训练过程中对多语言的编码和解码部分作了内部实现的剖析和讲解如果你还对其它部分如BPE算法感兴趣下面的参考内容或许能为你提供进一步的帮助。 参考阅读 带你从零认识语言模型手搓BPE算法什么是tokenizer
http://www.dnsts.com.cn/news/183151.html

相关文章:

  • 网站建设公司联系电话上海建筑室内设计有限公司
  • 做查询网站有哪些工作室网站制作
  • 临汾网站建设 吕梁网站建设建设网站列表
  • 网站注册页面设计wordpress音乐播放页面
  • 哪些企业会考虑做网站网站设计开发软件网页美化工具
  • 怎么学网站开发建设银行官方网站个人系统板块修改
  • 做公司网站用什么系统网站开发的流行架构
  • 打开一个网站在建设中石碣网站仿做
  • 时尚美容网站建设网站建设方案计划书人员规划
  • 专业做高端网站如何开发微信小程序
  • 微信视频网站建设多少钱免费网站建设平台
  • 网站建设的心得体会onethink 网站
  • 一般网站建设都用什么字体开周边网站怎么做品牌
  • 深圳营销网站建设服务wordpress 设置登陆
  • 搜索网站制作教程上海网站邮箱制作
  • 电子商务网站建设与管理基础个人网站备案内容不合格
  • 个人网站建设多少钱电商小程序名字
  • 怎么实现网站注册页面手机网站cms
  • 网站建设分几块查公司信息的网站是哪个网站
  • 设计师 英文网站购物商城网站的制作
  • 东莞网站建设优化诊断项目工程监理公司网站建设方案
  • 医疗网站建设及优化方案珠海做快照网站电话
  • 网页设计与网站建设书宝坻集团网站建设
  • 怎么拥有自己的网站做淘宝团购的网站
  • 多媒体教学网站的建设的论文阐述建站流程
  • 海洋网站建设怎么样哪个网站可以代做软件
  • 建设银行手机银行官方网站下载安装固定在网站底部
  • 网站建设人员工作职责标杆建设网站
  • 电子元件做的比较好的网站南京华夏商务网做网站怎么样
  • 广东深圳网站建设方便商城网站如何搭建