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

huggingface笔记:gpt2

0 使用的tips

  • GPT-2是一个具有绝对位置嵌入的模型,因此通常建议在输入的右侧而不是左侧填充
  • GPT-2是通过因果语言建模(CLM)目标进行训练的,因此在预测序列中的下一个标记方面非常强大
    • 利用这一特性,GPT-2可以生成语法连贯的文本
  • GPT-2可以接受past_key_values(对于PyTorch)或past(对于TF)作为输入
    • 这些是先前计算的键/值注意力对。‘
    • 使用这个(past_key_values或past)值可以防止模型在文本生成过程中重新计算预计算的值
  • 启用scale_attn_by_inverse_layer_idx和reorder_and_upcast_attn标志将应用Mistral的训练稳定性改进(仅适用于PyTorch)

1 基本实例

from transformers import AutoModelForCausalLM, AutoTokenizermodel = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")prompt = "GPT2 is a model developed by OpenAI."input_ids = tokenizer(prompt, return_tensors="pt").input_idsgen_tokens = model.generate(input_ids,do_sample=True,temperature=0.9,max_length=100,
)
gen_text = tokenizer.batch_decode(gen_tokens)[0]print(gen_text)
'''
GPT2 is a model developed by OpenAI. It helps to define the neural network of a person with Autism. The researchers have previously identified the basic network of neurons in the brain responsible for processing emotional information. They also found that the person with Autism has similar information processing abilities as other people with similar intelligence.The researchers say that it's important to look beyond the normal limitations of the human brain. "This type of neuroimaging has been really important," explains Michael A. Be
'''

2 GPT2Config

  • 用于存储 GPT2Model配置的配置类。
  • 根据指定的参数实例化一个 GPT-2 模型,定义模型架构
  • 使用默认值实例化配置将产生类似于 GPT-2 openai-community/gpt2 架构的配置:

2.1 主要参数

vocab_size(int, 可选,默认值为 50257) — GPT-2 模型的词汇表大小
n_positions(int, 可选,默认值为 1024) — 该模型可能使用的最大序列长度。
n_embd(int, 可选,默认值为 768) — 嵌入和隐藏状态的维度
n_layer(int, 可选,默认值为 12) — Transformer 编码器中的隐藏层数量
n_head(int, 可选,默认值为 12) — Transformer 编码器中每个注意力层的注意力头数量
n_inner(int, 可选) — 内部前馈层的维度。设置为 None 将其设置为 4 * n_embd
activation_function

(str, 可选,默认值为 "gelu_new") — 激活函数

可在以下列表中选择 ["relu", "silu", "gelu", "tanh", "gelu_new"]

resid_pdrop

(float, 可选,默认值为 0.1) —

嵌入、编码器和池化器中所有全连接层的丢弃概率

embd_pdrop(float, 可选,默认值为 0.1) — 嵌入的丢弃率
attn_pdrop(float, 可选,默认值为 0.1) — 注意力的丢弃率
layer_norm_epsilon(float, 可选,默认值为 1e-05) — 层归一化层中使用的epsilon值
initializer_range(float, 可选,默认值为 0.02) — 初始化所有权重矩阵时截断正态初始化器的标准差
scale_attn_weights(bool, 可选,默认值为 True) — 通过除以 sqrt(hidden_size) 来缩放注意力权重
bos_token_id(int, 可选,默认值为 50256) — 词汇表中句子起始标记的 ID
eos_token_id(int, 可选,默认值为 50256) — 词汇表中句子结束标记的 ID
scale_attn_by_inverse_layer_idx(bool, 可选,默认值为 False) — 是否另外通过 1 / (layer_idx + 1) 缩放注意力权重

2.2 举例

from transformers import GPT2Config, GPT2Model# 初始化 GPT2 配置
configuration = GPT2Config()configuration
'''
GPT2Config {"activation_function": "gelu_new","attn_pdrop": 0.1,"bos_token_id": 50256,"embd_pdrop": 0.1,"eos_token_id": 50256,"initializer_range": 0.02,"layer_norm_epsilon": 1e-05,"model_type": "gpt2","n_embd": 768,"n_head": 12,"n_inner": null,"n_layer": 12,"n_positions": 1024,"reorder_and_upcast_attn": false,"resid_pdrop": 0.1,"scale_attn_by_inverse_layer_idx": false,"scale_attn_weights": true,"summary_activation": null,"summary_first_dropout": 0.1,"summary_proj_to_labels": true,"summary_type": "cls_index","summary_use_proj": true,"transformers_version": "4.41.2","use_cache": true,"vocab_size": 50257
}
'''
# 根据配置初始化模型(具有随机权重)
model = GPT2Model(configuration)

3 GPT2Tokenizer

注:GPT2分词器经过训练将空格视为标记的一部分,因此一个单词在句子的开头(没有空格)或其他地方将被编码为不同的方式

3.1 主要参数

vocab_file词汇文件的路径
merges_file合并文件的路径
unk_token

(str, 可选,默认值为 "")

— 未知标记。不在词汇表中的标记无法转换为 ID,将被设置为此标记

bos_token(str, 可选,默认值为 "") — 序列开始标记
eos_token(str, 可选,默认值为 "") — 序列结束标记
pad_token(str, 可选) — 用于填充的标记,例如在批处理不同长度的序列时
add_prefix_space

(bool, 可选,默认值为 False) —

是否在输入的开头添加一个空格。这允许将前导词视为任何其他词一样处理。

add_bos_token

(bool, 可选,默认值为 False) —

是否在输入的开头添加一个序列开始标记。这允许将前导词视为任何其他词一样处理

3.2 举例

from transformers import GPT2Tokenizertokenizer = GPT2Tokenizer.from_pretrained("openai-community/gpt2")tokenizer("Hello world"),tokenizer(" Hello world")
'''
({'input_ids': [15496, 995], 'attention_mask': [1, 1]},{'input_ids': [18435, 995], 'attention_mask': [1, 1]})
'''

4 GPT2TokenizerFast

4.1 参数、

vocab_file词汇文件的路径
merges_file合并文件的路径
unk_token

(str, 可选,默认值为 "")

— 未知标记。不在词汇表中的标记无法转换为 ID,将被设置为此标记

bos_token(str, 可选,默认值为 "") — 序列开始标记
eos_token(str, 可选,默认值为 "") — 序列结束标记
add_prefix_space

(bool, 可选,默认值为 False) —

是否在输入的开头添加一个空格。这允许将前导词视为任何其他词一样处理。

4.2 举例

和GPT2Tokenizer类似 

from transformers import GPT2TokenizerFasttokenizer = GPT2TokenizerFast.from_pretrained("openai-community/gpt2")tokenizer("Hello world"),tokenizer(" Hello world")
'''
({'input_ids': [15496, 995], 'attention_mask': [1, 1]},{'input_ids': [18435, 995], 'attention_mask': [1, 1]})
'''

4.3 和GPT2Tokenizer的区别

底层库

  • GPT2TokenizerFast:基于 HuggingFace 的 tokenizers 库,这个库使用 Rust 实现了快速的分词算法,特别是字节对编码(Byte-Pair Encoding, BPE)。
  • GPT2Tokenizer:基于 Python 实现,使用较慢的分词方法。

性能

  • GPT2TokenizerFast:通常更快且更高效,特别是在处理大批量文本时。这是由于其使用了低级语言(Rust)的高效实现。
  • GPT2Tokenizer:相对较慢,因为它是纯 Python 实现的,计算效率较低。

5 GPT2DoubleHeadsModelOutput

预测两个句子是否连续的模型输出的基类

6 GPT2Model

裸 GPT-2 模型,输出原始的隐藏状态,没有任何特定的头部

6.1 forward 方法

6.1.1 参数

input_ids

(torch.LongTensor,形状为 (batch_size, input_ids_length))

输入序列标记在词汇表中的索引。

如果使用 past_key_values,则只有未计算 pastinput_ids 需要传递为 input_ids

past_key_values

Tuple[Tuple[torch.Tensor]],长度为 config.n_layers

包含模型计算的预计算隐藏状态(注意力块中的键和值)。

可以用来加速顺序解码。输入的 input_ids 不应包含已传递 pastinput_ids

attention_mask

torch.FloatTensor,形状为 (batch_size, sequence_length),可选

掩码,用于避免在填充标记索引上执行注意力。

掩码值选择为 [0, 1]:1 表示未被掩码的标记,0 表示被掩码的标记。

token_type_ids

(torch.LongTensor,形状为 (batch_size, input_ids_length),可选) —

段标记索引,用于指示输入的第一部分和第二部分。

索引选择为 [0, 1]:0 对应句子 A 标记,1 对应句子 B 标记。

position_ids

(torch.LongTensor,形状为 (batch_size, sequence_length),可选)

每个输入序列标记在位置嵌入中的位置索引。

选择范围为 [0, config.max_position_embeddings - 1]

head_mask

(torch.FloatTensor,形状为 (num_heads,) 或 (num_layers, num_heads),可选) —

掩码,用于取消选择的自注意力模块头部。

掩码值选择为 [0, 1]:1 表示头部未被掩码,0 表示头部被掩码

inputs_embeds

(torch.FloatTensor,形状为 (batch_size, sequence_length, hidden_size),可选)

可以选择直接传递嵌入表示而不是 input_ids

encoder_hidden_states(torch.FloatTensor,形状为 (batch_size, sequence_length, hidden_size),可选) — 编码器隐藏状态。
encoder_attention_mask(torch.FloatTensor,形状为 (batch_size, sequence_length),可选) — 编码器注意力掩码。
use_cache(bool, 可选) — 如果设置为 True,则返回 past_key_values 键值状态,可用于加速解码
output_attentions(bool, 可选) — 是否返回所有注意力层的注意力张量
output_hidden_states(bool, 可选) — 是否返回所有层的隐藏状态

6.1.2 返回值

last_hidden_state

(torch.FloatTensor,形状为 (batch_size, sequence_length, hidden_size)) — 模型最后一层的隐藏状态序列。

如果使用 past_key_values,则仅输出形状为 (batch_size, 1, hidden_size) 的序列的最后一个隐藏状态。

past_key_values

tuple(tuple(torch.FloatTensor)),可选,当传递 use_cache=True 时返回或 config.use_cache=True 时返回)

长度为 config.n_layers 的元组,每个元组包含形状为 (batch_size, num_heads, sequence_length, embed_size_per_head) 的 2 个张量

用来加速顺序解码

hidden_states

(tuple(torch.FloatTensor),可选,当传递 output_hidden_states=True 时返回或 config.output_hidden_states=True 时返回) 

包含 torch.FloatTensor 的元组(如果模型具有嵌入层,则为嵌入输出的一个 + 每层输出的一个),形状为 (batch_size, sequence_length, hidden_size)。

模型在每层输出的隐藏状态加上可选的初始嵌入输出的隐藏状态。

attentions

(tuple(torch.FloatTensor),可选,当传递 output_attentions=True 时返回或 config.output_attentions=True 时返回)

包含 torch.FloatTensor 的元组(每层一个),形状为 (batch_size, num_heads, sequence_length, sequence_length)。

注意力 softmax 后的注意力权重,用于计算自注意力头中的加权平均值。

cross_attentions

(tuple(torch.FloatTensor),可选,当传递 output_attentions=Trueconfig.add_cross_attention=True 时返回或 config.output_attentions=True 时返回)

包含 torch.FloatTensor 的元组(每层一个),形状为 (batch_size, num_heads, sequence_length, sequence_length)。

解码器交叉注意力层的注意力权重,在注意力 softmax 后,用于计算交叉注意力头中的加权平均值。

6.1.3 举例

from transformers import AutoTokenizer, GPT2Model
import torchtokenizer = AutoTokenizer.from_pretrained("openai-community/gpt2")
model = GPT2Model.from_pretrained("openai-community/gpt2")inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
outputs = model(**inputs)last_hidden_states = outputs.last_hidden_state
last_hidden_states
'''
tensor([[[-9.3295e-06, -1.4021e-01, -2.0845e-01,  ..., -1.5329e-01,-6.7826e-02, -1.9630e-01],[ 4.1949e-01,  2.3525e-01,  3.4816e-01,  ...,  4.5321e-02,1.5447e-01,  1.9546e-02],[-7.0056e-02,  2.6082e-01, -2.9146e-01,  ...,  9.0979e-02,4.9659e-01, -4.1824e-01],[-1.9695e-01, -2.9247e-01, -1.4119e-01,  ..., -8.9255e-02,-2.2392e-01,  1.2212e-01],[-6.4193e-01, -1.0236e-01, -4.2129e-01,  ...,  6.8697e-02,-5.1117e-01,  5.0044e-01],[ 4.1290e-03, -3.1455e-02, -1.0823e+00,  ..., -5.0159e-02,-3.0878e-02,  4.3480e-01]]], grad_fn=<ViewBackward0>)
'''

相关文章:

huggingface笔记:gpt2

0 使用的tips GPT-2是一个具有绝对位置嵌入的模型&#xff0c;因此通常建议在输入的右侧而不是左侧填充GPT-2是通过因果语言建模&#xff08;CLM&#xff09;目标进行训练的&#xff0c;因此在预测序列中的下一个标记方面非常强大 利用这一特性&#xff0c;GPT-2可以生成语法连…...

一次业务的批量数据任务的处理优化

文章目录 一次业务的批量数据任务的处理优化业务背景1.0版本 分批处理模式2.0版本 平衡任务队列模式3.0版本 优化调度平衡任务队列模式总结 一次业务的批量数据任务的处理优化 业务背景 一个重新生成所有客户的财务业务指标数据的批量数据处理任务。 1.0版本 分批处理模式 …...

新能源汽车充电站远程监控系统S275钡铼技术无线RTU

新能源汽车充电站的远程监控系统在现代城市基础设施中扮演着至关重要的角色&#xff0c;而钡铼技术的S275无线RTU作为一款先进的物联网数据监测采集控制短信报警终端&#xff0c;为充电站的安全运行和高效管理提供了强大的技术支持。 技术特点和功能 钡铼S275采用了基于UCOSI…...

海外视频媒体发布/发稿:如何在国外媒体以视频的形式宣发

1. 背景介绍 在如今数字化时代&#xff0c;每个国家都拥有着各自的视频媒体平台&#xff0c;而主流媒体也都纷纷加入了视频发布的行列。视频媒体的宣发形式主要包括油管Youtube等视频分享平台&#xff0c;以及图文配合的发布方式。通过在视频中夹带链接&#xff0c;媒体可以以…...

HTML 【实用教程】(2024最新版)

核心思想 —— 语义化 【面试题】如何理解 HTML 语义化 ?仅通过标签便能判断内容的类型&#xff0c;特别是区分标题、段落、图片和表格 增加代码可读性&#xff0c;让人更容易读懂对SEO更加友好&#xff0c;让搜索引擎更容易读懂 html 文件的基本结构 html 文件的文件后缀为 …...

How to Describe Figures in a Research Article

How to Describe Figures in a Research Article DateAuthorVersionNote2024.07.10Dog TaoV1.0Finish the document. 文章目录 How to Describe Figures in a Research ArticleGeneral GuidelinesDetailed DescriptionsCommon Describing Phrases Effective communication of …...

昇思MindSpore学习入门-CELL与参数一

Cell作为神经网络构造的基础单元&#xff0c;与神经网络层(Layer)的概念相对应&#xff0c;对Tensor计算操作的抽象封装&#xff0c;能够更准确清晰地对神经网络结构进行表示。除了基础的Tensor计算流程定义外&#xff0c;神经网络层还包含了参数管理、状态管理等功能。而参数(…...

【k8s中安装rabbitmq】k8s中安装rabbitmq并搭建镜像集群-hostpath版

文章目录 简介一.条件及环境说明二.需求说明三.实现原理及说明四.详细步骤4.1.规划节点标签4.2.创建configmap配置4.3.创建三个statefulset和service headless配置4.4.创建service配置 五.安装完后的配置六.安装说明 简介 k8s集群中搭建rabbitmq集群服务一般都会用到pvc&#x…...

(5) 深入探索Python-Pandas库的核心数据结构:Series详解

目录 前言1. Series 简介2. Series的特点3. Series的创建3.1 使用列表创建Series3.2 使用字典创建Series3.3 使用列表和自定义索引创建Series3.4 指定数据类型和名称 4. Series的索引/切片4.1 下标索引&#xff1a;基于整数位置的索引4.2 基于标签的索引4.3 切片4.4 使用.loc[]…...

JAVA之开发神器——IntelliJ IDEA的下载与安装

一、IDEA是什么&#xff1f; IEAD是JetBrains公司开发的专用于java开发的一款集成开发环境。由于其功能强大且符合人体工程学&#xff08;就是更懂你&#xff09;的优点&#xff0c;深受java开发人员的喜爱。目前在java开发工具中占比3/4。如果你要走java开发方向&#xff0c;那…...

通过Umijs从0到1搭建一个React项目

有一阵时间没写react了&#xff0c;今天通过umi搭建一个demo项目复习一下react&#xff1b;umi是一个可扩展的企业级前端应用框架&#xff0c;在react市场中还是比较火的一个框架。 Umi官方文档&#xff1a;Umi 介绍 (umijs.org) 一、构建项目。 1、安装包管理工具。 官方推…...

Redis 数据过期及淘汰策略

Redis 数据过期及淘汰策略 过期策略 定时过期 在设置key​的过期时间的同时&#xff0c;为该key​创建一个定时器&#xff0c;让定时器在key​的过期时间来临时&#xff0c;对key进行删除。到过期时间就会立即清除。该策略可以立即清除过期的数据&#xff0c;对内存很友好&a…...

vue vite+three在线编辑模型导入导出

文章目录 序一、1.0.0版本1.新增2.编辑3.导出4.导入 总结 序 要实现一个类似于数字孪生的场景 可以在线、新增、删除模型 、以及编辑模型的颜色、长宽高 然后还要实现 编辑完后 保存为json数据 记录模型数据 既可以导入也可以导出 一、1.0.0版本 1.新增 先拿建议的立方体来…...

去水印小程序源码修复版-前端后端内置接口+第三方接口

去水印小程序源码&#xff0c;前端后端&#xff0c;内置接口第三方接口&#xff0c; 修复数据库账号密码错误问题&#xff0c;内置接口支持替换第三方接口&#xff0c; 文件挺全的&#xff0c;可以添加流量主代码&#xff0c;搭建需要准备一台服务器&#xff0c;备案域名和http…...

机器学习:预测评估8类指标

机器学习&#xff1a;8类预测评估指标 R方值、平均值绝对误差值MAE、均方误差MSE、均方误差根EMSE、中位数绝对误差MAD、平均绝对百分误差MAPE、可解释方差分EVS、均方根对数误差MLSE。 一、R方值 1、说明&#xff1a; R方值&#xff0c;也称为确定系数或拟合优度&#xff…...

【深度学习基础】MAC pycharm 专业版安装与激活

文章目录 一、pycharm专业版安装二、激活 一、pycharm专业版安装 PyCharm是一款专为Python开发者设计的集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在帮助用户在使用Python语言开发时提高效率。以下是对PyCharm软件的详细介绍&#xff0c;包括其作用和主要功能&…...

排序相关算法--1.插入排序+冒泡排序回顾

1.基本分类 2.插入排序 特点&#xff1a;有实践意义&#xff08;例如后期快排的优化&#xff09;&#xff0c;适应性强&#xff0c;一般不会到时间复杂度最坏的情况。 将第一个元素视为已经排好序的序列。取出下一个元素&#xff0c;在已经排好序的序列中从后往前比较&#xf…...

变阻器的故障排除方法有哪些?

变阻器&#xff0c;特别是滑动变阻器&#xff0c;作为电子电路中的常见元件&#xff0c;其故障排除方法主要依据具体的故障现象来确定。以下是一些常见的故障现象及其排除方法&#xff1a; 一、接触不良 现象&#xff1a;电阻器不起作用或电压不稳定。 排除方法&#xff1a; …...

软考《信息系统运行管理员》-3.1信息系统设施运维的管理体系

3.1信息系统设施运维的管理体系 1 信息系统设施运维的对象 基础环境 主要包括信息系统运行环境(机房、设备间、配线室、基站、云计算中心 等)中的空调系统、供配电系统、通信应急设备系统、防护设备系统(如消防系统、安全系统) 等&#xff0c;能维持系统安全正常运转&#xf…...

Nginx重定向

Nginx重定向 location 匹配 location匹配的就是后面的URL /WordPress 192.168.118.10/wordpress location匹配的分类和优先级 1.精确匹配 location/对字符串进行完全匹配,必须完全符合2.正则匹配 ^~ 前缀匹配,以什么为开头~ 区分大小写的匹配~* 不区分大小写!~: 区分大小…...

Arm嵌入式多线程编程:原理、实践与优化

1. Arm嵌入式开发中的多线程编程基础在嵌入式系统开发中&#xff0c;多线程编程是提高系统响应能力和资源利用率的重要手段。Arm架构作为嵌入式领域的主流处理器架构&#xff0c;其编译器工具链对多线程编程提供了完善的支持。不同于通用计算环境&#xff0c;嵌入式系统的多线程…...

市场营销Agent:自动生成内容与投放策略

市场营销Agent:自动生成内容与投放策略——从痛点分析到落地实践的全栈指南 引言 痛点引入 在数字营销的战场上,每天都有无数的团队在重复着「内容绞肉机」和「投放试错场」的噩梦: 内容产出端:为了覆盖小红书、抖音、知乎、微信公众号、TikTok、LinkedIn等数十个主流渠…...

SteamAutoCrack技术深度解析:架构设计与实现原理揭秘

SteamAutoCrack技术深度解析&#xff1a;架构设计与实现原理揭秘 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack SteamAutoCrack是一款基于.NET 10.0框架开发的Steam游戏自动破解工具&…...

Spring Boot项目整合阿里云OSS上传,如何避免Nginx代理下的405坑?

Spring Boot整合阿里云OSS上传的Nginx避坑指南&#xff1a;彻底解决405错误 在前后端分离架构中&#xff0c;文件上传功能几乎是每个Web应用的标配。当我们将Spring Boot与阿里云OSS结合使用时&#xff0c;Nginx作为反向代理常常会带来一个棘手的405 Method Not Allowed错误。这…...

MATLAB 2018a/2023b实测:Libsvm安装后如何用自带数据集快速验证与跑通第一个模型

MATLAB 2018a/2023b实战&#xff1a;Libsvm安装后快速验证与模型跑通全流程 当你第一次在MATLAB中成功安装Libsvm后&#xff0c;那种兴奋感可能很快会被"接下来该做什么"的迷茫所取代。别担心&#xff0c;这篇文章将带你用Libsvm自带的heart_scale数据集&#xff0c;…...

【PyTorch实战】从零构建Prototypical Network:小样本图像分类的度量学习核心

1. 小样本学习与Prototypical Network基础 当你第一次听说"小样本学习"时&#xff0c;可能会觉得这是个遥不可及的高深概念。其实它的核心思想很简单&#xff1a;就像人类能通过少量例子快速学习新事物一样&#xff0c;让AI模型也具备这种能力。想象一下&#xff0c;…...

Spring AI 2.0 开发Java Agent智能体 - 会话记忆(Chat Memory)

大家好&#xff0c;我是Java1234_小锋老师&#xff0c;最近更新《2027版本 Spring AI 2.0 开发Java Agent智能体 视频教程》专辑&#xff0c;感谢大家支持。本课程主要介绍和讲解Spring AI 2.0简介&#xff0c;Spring AI 2.0 HelloWorld搭建&#xff0c;Advisors — 拦截器模式…...

C++项目集成Tesseract 5.x踩坑实录:从编译选项到内存管理的完整避坑指南

C项目集成Tesseract 5.x踩坑实录&#xff1a;从编译选项到内存管理的完整避坑指南 在计算机视觉和文档处理领域&#xff0c;Tesseract OCR引擎以其开源免费、多语言支持和较高的识别准确率&#xff0c;成为众多C项目的首选集成方案。然而&#xff0c;从源码编译到生产环境部署&…...

AI Token中转副业火爆!小白也能快速上手?3小时建站+真实盈利模式全解析!

很多观望的小白最纠结两个核心问题&#xff1a;普通人搭建一个Token中转站到底要多久&#xff1f;建好之后真的能赚钱吗&#xff0c;真实赚钱逻辑是什么&#xff1f; 今天不讲噱头、不吹月入几万&#xff0c;结合行业真实现状、新手实操经验&#xff0c;一次性讲透搭建耗时、成…...

一天怎么完成论文初稿

写论文这件事&#xff0c;从选题到完稿&#xff0c;哪一步都能卡掉你半条命。我身边不少读研读博的同学&#xff0c;白天泡实验室做实验&#xff0c;晚上挤时间写论文&#xff0c;熬了一两个月出初稿&#xff0c;结果格式不对、文献零散&#xff0c;还要和同门改来改去&#xf…...