news 2026/8/17 3:11:53

面试-Tokenizer训练

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面试-Tokenizer训练

1 代码

# 注:不建议再重复训练tokenizer(“词典”),MiniMind已自带,此脚本仅供学习和参考。基于不同词典训练的模型将导致输出完全不统一,降低社区的模型复用性# Note: It is not recommended to re-train the tokenizer. MiniMind already includes one. This script is for learning and reference only. Training models with different tokenizers will lead to inconsistent outputs and reduce model reusability in the community.importosimportjsonfromtokenizersimportdecoders,models,pre_tokenizers,trainers,Tokenizer DATA_PATH='../dataset/pretrain_hq.jsonl'TOKENIZER_DIR='../model_learn_tokenizer/'VOCAB_SIZE=6400defget_texts(data_path):withopen(data_path,'r',encoding='utf-8')asf:fori,lineinenumerate(f):ifi>=10000:break# 实验性,可只用前10000行测试data=json.loads(line)yielddata['text']deftrain_tokenizer(data_path,tokenizer_dir,vocab_size):tokenizer=Tokenizer(models.BPE())tokenizer.pre_tokenizer=pre_tokenizers.ByteLevel(add_prefix_space=False)trainer=trainers.BpeTrainer(vocab_size=vocab_size,special_tokens=["<|endoftext|>","<|im_start|>","<|im_end|>"],show_progress=True,initial_alphabet=pre_tokenizers.ByteLevel.alphabet())texts=get_texts(data_path)tokenizer.train_from_iterator(texts,trainer=trainer)tokenizer.decoder=decoders.ByteLevel()asserttokenizer.token_to_id("<|endoftext|>")==0asserttokenizer.token_to_id("<|im_start|>")==1asserttokenizer.token_to_id("<|im_end|>")==2os.makedirs(tokenizer_dir,exist_ok=True)tokenizer.save(os.path.join(tokenizer_dir,"tokenizer.json"))tokenizer.model.save(tokenizer_dir)config={"add_bos_token":False,"add_eos_token":False,"add_prefix_space":False,"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":32768,"pad_token":"<|endoftext|>","sp_model_kwargs":{},"spaces_between_special_tokens":False,"tokenizer_class":"PreTrainedTokenizerFast","unk_token":"<|endoftext|>","chat_template":"{%- if tools %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0].role == 'system' %}\n {{- messages[0].content + '\\n\\n' }}\n {%- endif %}\n {{- \"# Tools\\n\\nYou may call one or more functions to assist with the user query.\\n\\nYou are provided with function signatures within <tools></tools> XML tags:\\n<tools>\" }}\n {%- for tool in tools %}\n {{- \"\\n\" }}\n {{- tool | tojson }}\n {%- endfor %}\n {{- \"\\n</tools>\\n\\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\\n<tool_call>\\n{\\\"name\\\": <function-name>, \\\"arguments\\\": <args-json-object>}\\n</tool_call><|im_end|>\\n\" }}\n{%- else %}\n {%- if messages[0]['role'] == 'system' -%}\n {{- '<|im_start|>system\\n' + messages[0]['content'] + '<|im_end|>\\n' }}\n {%- else -%}\n {{- '<|im_start|>system\\nYou are a helpful assistant<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}\n{%- for message in messages[::-1] %}\n {%- set index = (messages|length - 1) - loop.index0 %}\n {%- if ns.multi_step_tool and message.role == \"user\" and message.content is string and not(message.content.startswith('<tool_response>') and message.content.endswith('</tool_response>')) %}\n {%- set ns.multi_step_tool = false %}\n {%- set ns.last_query_index = index %}\n {%- endif %}\n{%- endfor %}\n{%- for message in messages %}\n {%- if message.content is string %}\n {%- set content = message.content %}\n {%- else %}\n {%- set content = '' %}\n {%- endif %}\n {%- if (message.role == \"user\") or (message.role == \"system\" and not loop.first) %}\n {{- '<|im_start|>' + message.role + '\\n' + content + '<|im_end|>' + '\\n' }}\n {%- elif message.role == \"assistant\" %}\n {{- '<|im_start|>' + message.role + '\\n' + content }}\n {%- if message.tool_calls %}\n {%- for tool_call in message.tool_calls %}\n {%- if (loop.first and content) or (not loop.first) %}\n {{- '\\n' }}\n {%- endif %}\n {%- if tool_call.function %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '<tool_call>\\n{\"name\": \"' }}\n {{- tool_call.name }}\n {{- '\", \"arguments\": ' }}\n {%- if tool_call.arguments is string %}\n {{- tool_call.arguments }}\n {%- else %}\n {{- tool_call.arguments | tojson }}\n {%- endif %}\n {{- '}\\n</tool_call>' }}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if loop.first or (messages[loop.index0 - 1].role != \"tool\") %}\n {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n<tool_response>\\n' }}\n {{- content }}\n {{- '\\n</tool_response>' }}\n {%- if loop.last or (messages[loop.index0 + 1].role != \"tool\") %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n {%- if enable_thinking is defined and enable_thinking is false %}\n {{- '<think>\\n\\n</think>\\n\\n' }}\n {%- endif %}\n{%- endif %}"}withopen(os.path.join(tokenizer_dir,"tokenizer_config.json"),"w",encoding="utf-8")asf:json.dump(config,f,ensure_ascii=False,indent=4)print("Tokenizer training completed.")defeval_tokenizer(tokenizer_dir):fromtransformersimportAutoTokenizer tokenizer=AutoTokenizer.from_pretrained(tokenizer_dir)messages=[{"role":"system","content":"你是一个优秀的聊天机器人,总是给我正确的回应!"},{"role":"user","content":'你来自哪里?'},{"role":"assistant","content":'我来自地球'}]new_prompt=tokenizer.apply_chat_template(messages,tokenize=False)print('-'*100)print(new_prompt)print('-'*100)print('tokenizer词表长度:',len(tokenizer))model_inputs=tokenizer(new_prompt)print('encoder长度:',len(model_inputs['input_ids']))response=tokenizer.decode(model_inputs['input_ids'],skip_special_tokens=False)print('decoder一致性:',response==new_prompt,"\n")print('-'*100)print('流式解码(字节缓冲)测试:')input_ids=model_inputs['input_ids']token_cache=[]fortidininput_ids:token_cache.append(tid)current_decode=tokenizer.decode(token_cache)ifcurrent_decodeand'\ufffd'notincurrent_decode:display_ids=token_cache[0]iflen(token_cache)==1elsetoken_cache raw_tokens=[tokenizer.convert_ids_to_tokens(int(t))fortin(token_cacheifisinstance(token_cache,list)else[token_cache])]print(f'Token ID:{str(display_ids):15}-> Raw:{str(raw_tokens):20}-> Decode Str:{current_decode}')token_cache=[]if__name__=='__main__':train_tokenizer(DATA_PATH,TOKENIZER_DIR,VOCAB_SIZE)eval_tokenizer(TOKENIZER_DIR)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/9 21:47:25

提示工程架构师进阶:打造企业级代码生成工具实战

提示工程架构师进阶:打造企业级代码生成工具实战 一、引言 在当今软件开发的快节奏环境中,提高开发效率和质量是每个企业追求的目标。代码生成工具作为一种能够自动化生成部分代码的利器,正逐渐在企业级开发中崭露头角。对于提示工程架构师而言,打造企业级代码生成工具不…

作者头像 李华
网站建设 2026/8/16 12:05:33

自建一个Agent很难吗?一语道破,万语难明

最近花了一周左右的时间给内部的一个传统研发平台接入了 Agent 开发的能力&#xff0c;很多同学对 Agent 的底层实现非常感兴趣&#xff0c;所以此篇给大家介绍下我是怎么做的&#xff0c;希望能对想自建 Agent 的同学有所启发。 因人力原因&#xff0c;有些细节方案问题没太做…

作者头像 李华
网站建设 2026/8/14 11:51:08

【第1章·第14节】自适应PID控制器的simulink建模与仿真1——理论分析

目录 1.自适应PID控制器概述 2.自适应PID控制器的理论分析 2.1 PID控制器误差 2.2 自适应PID控制器调整策略 2.3 自适应PID控制参数更新 1.自适应PID控制器概述 自适应PID控制器核心是通过实时反馈误差,动态调整比例系数kp、积分系数ki、微分系数kd,解决传统PID固定参数…

作者头像 李华
网站建设 2026/8/9 14:54:17

1.5亿,AI原生城市服务平台建设项目

1 月 30 日&#xff0c;福州市鼓楼区AI原生城市服务平台建设项目&#xff08;一期&#xff09;中标公告&#xff0c;中标金额&#xff1a;15084.0636万元&#xff0c;中标人&#xff1a;中国移动通信集团福建有限公司福州分公司。一、项目信息&#xff1a;项目名称&#xff1a;…

作者头像 李华
网站建设 2026/8/9 22:51:01

Spring Boot 应用启动速度优化全攻略

一、引言&#xff1a;Spring Boot 启动慢的常见痛点1.1 启动慢的现象本地开发时每次修改代码后重启需要30秒以上测试环境部署时启动时间超过1分钟生产环境容器启动缓慢影响弹性伸缩CI/CD流水线中构建-启动-测试周期过长1.2 启动速度的重要性开发效率&#xff1a;快速反馈循环是…

作者头像 李华