当我想使用DeepSpeed加速模型培训时,当我想评估验证数据集上的模型时会出现问题。这是问题代码段:
def evaluate(self, epoch_num=None, keep_all=True):
print("self.model:", self.model)
self.model = self.model.eval()
print("self.model after eval:", self.model)
then输出日志:
self.model: DeepSpeedEngine(
(module): TSTransformerEncoder(
(project_inp): Linear(in_features=6, out_features=128, bias=True)
(pos_enc): LearnablePositionalEncoding(
(dropout): Dropout(p=0.1, inplace=False)
)
(transformer_encoder): TransformerEncoder(
(layers): ModuleList(
(0-2): 3 x TransformerBatchNormEncoderLayer(
(self_attn): MultiheadAttention(
(out_proj): NonDynamicallyQuantizableLinear(in_features=128, out_features=128, bias=True)
)
(linear1): Linear(in_features=128, out_features=256, bias=True)
(dropout): Dropout(p=0.1, inplace=False)
(linear2): Linear(in_features=256, out_features=128, bias=True)
(norm1): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(norm2): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(dropout1): Dropout(p=0.1, inplace=False)
(dropout2): Dropout(p=0.1, inplace=False)
)
)
)
(output_layer): Linear(in_features=128, out_features=6, bias=True)
(dropout1): Dropout(p=0.1, inplace=False)
)
)
self.model after eval: None
没有使用DeepSpeed工具,可以对模型进行正常训练和评估。但是,在使用深速后,发生上述问题。
我初始化深速的方式:
model, optimizer, _, _ = deepspeed.initialize(
model=model,
optimizer=optimizer,
config_params=ds_config
)
ds_config文件:
{
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"optimizer": {
"params": {
"lr": 0.001,
"weight_decay": 0,
"optimizer_class": "optimizers.RAdam"
}
},
"zero_optimization": {
"stage": 1,
"overlap_comm": true,
"contiguous_gradients": true
},
"zero_allow_untested_optimizer": true,
"train_batch_size": 256,
"steps_per_print": 2000,
"wall_clock_breakdown": false
}
问题分析
self.model.eval()
仅将模型设置为评估模式,并且模型本身不会变为
None
。但是,实际输出表明调用self.model
方法后None
变为eval()
。我怀疑这可能与DeepSpeed的封装或配置有关,但我不确定特定原因。
wrilevant环境信息
Python版本Pytorch版本
-Deepspeed版本
eval
状态,但不会返回任何内容。这与返回模型本身的标准pytorcheval
代码不同。这意味着将模型设置为内部评估模式,但返回。这意味着,当您将
train
输出分配到self.model.eval()
通过None
时,您本质上是在运行
self.model.eval()
。
您可以将代码更改为:self.model
注意,这也适用于标准Pytorch模型 - self.model = self.model.eval()
主要更新模型对象的内部状态,因此对于self.model = None
模型和标准Pytorch模型,将模型对象重新分配到同一变量名称不必要。