第45篇:文本生成实战:使用GPT-2创作故事——体验AI的“创造力”(项目实战)
文章目录项目背景技术选型架构设计核心实现1. 准备模型与分词器2. 构建文本生成函数3. 体验不同的生成策略踩坑记录效果对比与项目扩展项目背景在之前的项目中我们处理的多是分类、预测等“理解型”任务。这次我想带大家玩点不一样的——让AI“创造”一个故事。文本生成尤其是开放式故事创作是检验语言模型“智能”程度的绝佳试金石。我记得第一次用GPT-2生成文本时那种看着连贯、甚至富有想象力的句子从模型里“流”出来的感觉非常震撼。它不再是简单地复述而是在“编造”。本项目我们就用Hugging Facetransformers库基于预训练的GPT-2模型从零搭建一个故事生成器亲身体验AI的“创造力”边界。技术选型为什么选择GPT-2而不是更新、更大的GPT-3或GPT-4这基于几个务实的考虑资源友好GPT-2特别是小号和小小号版本可以在消费级GPU甚至CPU上运行而GPT-3/4的API调用有成本且大模型本地部署门槛极高。开源可控GPT-2完全开源我们可以深入模型内部调整生成策略进行微调学习整个流程。这对于理解和掌握文本生成技术至关重要。效果足够对于故事生成这个场景GPT-2特别是774M参数版本的能力已经能产生令人惊喜的结果足以让我们体验核心乐趣和技术要点。因此我们的技术栈非常清晰核心模型Hugging Facetransformers库中的gpt2(或gpt2-medium)深度学习框架PyTorch辅助工具torch,transformers,tqdm(用于进度条)架构设计这个项目的架构非常简单直接是一个典型的“预训练模型生成策略”流水线。我们不涉及复杂的服务部署聚焦于生成逻辑本身。用户输入故事开头/提示词 ↓ [文本预处理与Tokenization] ↓ [加载预训练GPT-2模型与分词器] ↓ [核心文本生成循环] ├── 策略选择贪婪搜索、集束搜索、Top-k采样、Top-p采样 └── 生成控制最大长度、重复惩罚、温度参数 ↓ [Token解码为文本] ↓ 输出生成的故事段落核心在于生成循环和解码策略。不同的策略会极大影响生成故事的“创造性”、“连贯性”和“可读性”。核心实现让我们一步步用代码实现这个生成器。首先确保环境已安装必要库pip install transformers torch tqdm。1. 准备模型与分词器fromtransformersimportGPT2LMHeadModel,GPT2Tokenizerimporttorch# 加载预训练模型和分词器# 使用 gpt2 (124M参数) 以在CPU或内存较小的GPU上快速运行# 如果想效果更好可以尝试 gpt2-medium (774M参数)model_namegpt2tokenizerGPT2Tokenizer.from_pretrained(model_name)modelGPT2LMHeadModel.from_pretrained(model_name)# 将模型设置为评估模式关闭dropout等训练层model.eval()# 如果可用使用GPU加速devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)model.to(device)踩坑提示1GPT-2的分词器默认不会添加padding token。如果后续需要批量生成需要手动设置tokenizer.pad_token tokenizer.eos_token。我们本次是单条生成可暂不处理。2. 构建文本生成函数这是项目的核心。我们将实现一个支持多种解码策略的生成函数。defgenerate_story(prompt,max_length150,num_return_sequences1,strategytop_p,temperature1.0,top_k50,top_p0.95): 使用GPT-2生成故事续写。 参数: prompt: 故事开头的提示文本。 max_length: 生成文本的最大总长度包括提示。 num_return_sequences: 生成几个不同的故事版本。 strategy: 解码策略可选 greedy, beam, top_k, top_p。 temperature: 温度参数越高越随机越低越确定。 top_k: Top-k采样中的k值。 top_p: Top-p核采样中的p值。 # 将提示文本编码为模型输入的token IDinput_idstokenizer.encode(prompt,return_tensorspt).to(device)# 根据策略配置生成参数generation_config{max_length:max_length,num_return_sequences:num_return_sequences,pad_token_id:tokenizer.eos_token_id,# 设置结束符也为padding符do_sample:True,# 默认启用采样对于贪婪和集束搜索会覆盖temperature:temperature,}ifstrategygreedy:# 贪婪搜索每一步都选择概率最高的词generation_config.update({do_sample:False,num_beams:1})elifstrategybeam:# 集束搜索每一步保留多个最有可能的序列generation_config.update({do_sample:False,num_beams:5,early_stopping:True})elifstrategytop_k:# Top-k采样每一步从概率最高的k个词中随机选一个generation_config.update({top_k:top_k})elifstrategytop_p:# Top-p核采样每一步从累积概率超过p的最小词集合中随机选一个generation_config.update({top_p:top_p,top_k:0})# top_k0表示禁用top-k# 使用模型生成文本withtorch.no_grad():# 禁用梯度计算加快推理速度减少内存占用output_sequencesmodel.generate(input_idsinput_ids,**generation_config)# 解码生成的token ID为可读文本generated_stories[]forgenerated_sequenceinoutput_sequences:# 跳过输入提示部分只解码新生成的部分generated_sequencegenerated_sequence[len(input_ids[0]):]texttokenizer.decode(generated_sequence,skip_special_tokensTrue,clean_up_tokenization_spacesTrue)generated_stories.append(text)returngenerated_stories3. 体验不同的生成策略现在让我们用一个简单的提示词对比不同策略的效果。prompt在一个遥远的未来机器人学会了做梦。print(f提示词:{prompt}\n)strategies[greedy,beam,top_k,top_p]forsinstrategies:print(f--- 使用策略:{s.upper()}---)storiesgenerate_story(prompt,max_length100,strategys,temperature0.8ifsin[top_k,top_p]else1.0)print(stories[0][:200]...)# 打印前200个字符print()运行这段代码你会直观地看到贪婪搜索Greedy生成的故事通常最连贯、最安全但也最容易陷入重复循环比如不停地重复“机器人做梦做梦做梦……”缺乏新意。集束搜索Beam Search连贯性比贪婪搜索更好能一定程度避免重复但生成的故事可能过于“平庸”或模板化。Top-k / Top-p 采样这是让故事变得“有趣”和“有创意”的关键。通过引入随机性生成的情节往往更出人意料。Top-p核采样通常比Top-k更灵活和有效因为它动态调整候选词集合的大小。踩坑记录在实际操作中我遇到了几个典型问题这里分享给大家生成结果重复或退化这是文本生成的经典难题。表现为模型开始不断重复同一句话或词语。解决方案除了使用Top-p采样还可以在generate函数中设置repetition_penalty参数大于1.0如1.2对已出现过的token进行概率惩罚。或者使用no_repeat_ngram_size参数禁止特定长度的短语重复出现。生成内容无关或跑题模型可能会从“机器人做梦”突然跳到谈论“今天的天气”。解决方案这通常与提示词不够具体有关。尝试给出更详细、更具约束性的开头。例如“在一个遥远的未来一个负责清理城市的旧型号机器人第一次在待机时体验到了类似人类做梦的数据流。它梦见了”。此外适当降低temperature值如从1.0降到0.7可以让生成内容更聚焦。生成速度慢尤其是在使用beam search或生成长文本时。解决方案对于交互式应用可以考虑使用更小的模型distilgpt2。在生成时使用max_new_tokens参数替代max_length精确控制新生成长度避免不必要的计算。如果使用支持CUDA的GPU确保模型和输入数据都已.to(device)。奇怪的分词和空格生成文本中可能出现奇怪的符号或多余空格。解决方案确保在tokenizer.decode()时设置了skip_special_tokensTrue和clean_up_tokenization_spacesTrue。对于中文或其他语言可能需要使用专门的分词器如gpt2-chinese。效果对比与项目扩展经过多次尝试我发现在故事生成任务上“Top-p采样p值0.9-0.95配合适当的温度0.7-0.9”是平衡创造性、连贯性和趣味性的最佳组合。贪婪和集束搜索更适合需要高确定性的任务如代码补全或翻译。项目扩展思路微调模型找一些科幻小说、童话故事的文本数据对GPT-2进行微调让它生成特定风格的故事。构建Web应用使用Gradio或Streamlit快速搭建一个交互界面让用户输入提示词选择风格实时生成故事。多轮对话式生成模拟一个“AI说书人”用户输入“然后呢”来推动故事发展这需要维护一个不断增长的对话历史上下文。加入条件控制使用CTRL或Prompt Tuning等技术控制故事的情感悲伤/欢乐、流派科幻/武侠等属性。通过这个实战项目我们不仅运行了一个GPT-2模型更重要的是我们亲手调试了那些控制AI“创造力”的旋钮——温度、Top-p、重复惩罚等。你会发现所谓的AI创造力目前很大程度上是“可控的随机性”。如何设置这些参数让生成的故事既天马行空又不至于胡言乱语正是这门技术的艺术所在。动手试试吧给你的AI一个开头看看它会还你一个怎样的世界。如有问题欢迎评论区交流持续更新中…
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2563777.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!