#python #pytorch #gpu #cpu
Вопрос:
Я обучил ту же модель PyTorch в системе ubuntu с графическим процессором tesla k80, и я получил точность около 32%, но когда я запускаю ее с использованием процессора, точность составляет 43%. также установлены Cuda-инструментарий и библиотека cudnn. nvidia-драйвер: 470.63.01
версия nvcc: 10.1
каковы возможные причины такой большой разницы?
Для более подробной информации я использовал этот код https://github.com/copenlu/xformer-multi-source-domain-adaptation и адаптировал это для моей проблемы с ответом на вопрос, класс модели:
class MultiViewTransformerNetworkAveragingIndividuals(nn.Module):
Multi-view transformer network for domain adaptation
def __init__(self, bert_model, bert_config, n_domains: int = 2, n_classes: int = 2):
super(MultiViewTransformerNetworkAveragingIndividuals, self).__init__()
self.domain_experts = nn.ModuleList([AutoModelForQuestionAnswering.from_pretrained(bert_model,config=bert_config) for _ in range(n_domains)])
self.shared_bert = AutoModelForQuestionAnswering.from_pretrained(bert_model,config=bert_config)
self.n_domains = n_domains
self.n_classes = n_classes
# Default weight is averaging
self.weights = [1. / (self.n_domains 1)] * (self.n_domains 1)
self.average = False
def forward(
self,
input_ids: torch.LongTensor,
attention_mask: torch.LongTensor,
head_mask=None,
inputs_embeds=None,
start_positions=None,
end_positions=None,
output_attentions=None,
output_hidden_states=None,
return_dict=None,
domains: torch.LongTensor = None,
return_logits: bool = False
):
outputs = self.shared_bert(input_ids, attention_mask,head_mask=head_mask,inputs_embeds=inputs_embeds,output_attentions=output_attentions,
output_hidden_states=output_hidden_states,return_dict=return_dict)
logits_shared_start = outputs[0]
logits_shared_end = outputs[1]
softmax = nn.Softmax()
if not self.average:
if domains is not None:
logits = self.domain_experts[domains[0]](input_ids, attention_mask,head_mask=head_mask,inputs_embeds=inputs_embeds,output_attentions=output_attentions,
output_hidden_states=output_hidden_states,return_dict=return_dict)
logits_start=logits[0]
logits_end=logits[1]
# b x n_dom( 1) x nclasses
start_preds = softmax(logits_start)
end_preds = softmax(logits_end)
else:
logits_start = logits_shared_start
logits_end = logits_shared_end
# b x n_dom( 1) x nclasses
start_preds = softmax(logits_start)
end_preds = softmax(logits_end)
else:
logits_private = [self.domain_experts[d](input_ids, attention_mask,head_mask=head_mask,inputs_embeds=inputs_embeds,output_attentions=output_attentions,
output_hidden_states=output_hidden_states,return_dict=return_dict) for d in
range(self.n_domains)]
logits_private_start=[log_private[0] for log_private in logits_private]
logits_private_end=[log_private[1] for log_private in logits_private]
logits_start = logits_private_start [logits_shared_start]
logits_end = logits_private_end [logits_shared_end]
if return_logits:
return (logits_start,logits_end)
attn = torch.FloatTensor(self.weights).view(1, -1, 1)
# b x n_dom( 1) x nclasses
start_preds = torch.stack([softmax(logs) for logs in logits_start], dim=1)
end_preds = torch.stack([softmax(logs) for logs in logits_end], dim=1)
# Apply attention
start_preds = torch.sum(start_preds * attn, dim=1)
end_preds = torch.sum(end_preds * attn, dim=1)
outputs = (start_preds,end_preds,)
loss=None
if start_positions is not None and end_positions is not None:
if len(start_positions.size()) > 1:
start_positions = start_positions.squeeze(-1)
if len(end_positions.size()) > 1:
end_positions = end_positions.squeeze(-1)
# sometimes the start/end positions are outside our model inputs, we ignore these terms
ignored_index = start_preds.size(1)
start_positions.clamp_(0, ignored_index)
end_positions.clamp_(0, ignored_index)
# LogSoftmax NLLLoss
loss_fn = nn.NLLLoss()
xent = nn.CrossEntropyLoss()
s_loss = loss_fn(torch.log(start_preds), start_positions)
e_loss = loss_fn(torch.log(end_preds), end_positions)
loss_s=(s_loss e_loss/2)
loss=loss_s
s_loss_t=xent(logits_shared_start, start_positions)
e_loss_t=xent(logits_shared_end, end_positions)
loss_t=(s_loss_t e_loss_t)/2
loss =loss_t
# Strong supervision on in domain
#if domains is not None:
return QuestionAnsweringModelOutput(
loss=loss,
start_logits=start_preds,
end_logits=end_preds,
)
когда я запускаю этот код шаг за шагом, выходные данные модели (start_logits, end_logits и потери) отличаются от процессора к графическому процессору.
следует отметить, что семена инициализируются в первой из программ как:
# Set all the seeds
seed = args.seed
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
и результаты не меняются при многократных запусках.
Комментарии:
1. невозможно ответить без подробностей контекста, таких как архитектура модели, набор данных, обучающий конвейер и т.д.
2. Я отредактировал это, чтобы включить более подробную информацию
3. На это нетрудно ответить, так как мы знаем, что op использует cudnn, что уже создает проблему воспроизводимости.
4. У меня нет проблем с воспроизводимостью, потому что при запуске программы с процессором всегда получается точность 43%, а при запуске программы с графическим процессором всегда получается 32%. проблема в этой разнице между процессором и графическим процессором
Ответ №1:
Согласно странице документации Nvidia CUDNN:
- Воспроизводимость (детерминизм) По замыслу большинство подпрограмм cuDNN из данной версии генерируют одинаковые битовые результаты при выполнении на графических процессорах с одинаковой архитектурой и одинаковым количеством SMS. Однако битовая воспроизводимость не гарантируется в разных версиях, так как реализация данной процедуры может измениться. В текущем выпуске следующие процедуры не гарантируют воспроизводимость, поскольку они используют атомарные операции:
cudnnConvolutionBackwardFilter
когдаCUDNN_CONVOLUTION_BWD_FILTER_ALGO_0
илиCUDNN_CONVOLUTION_BWD_FILTER_ALGO_3
используетсяcudnnConvolutionBackwardData
когдаCUDNN_CONVOLUTION_BWD_DATA_ALGO_0
используетсяcudnnPoolingBackward
когдаCUDNN_POOLING_MAX
используетсяcudnnSpatialTfSamplerBackward
cudnnCTCLoss
иcudnnCTCLoss_v8
когдаCUDNN_CTC_LOSS_ALGO_NON_DETERMINSTIC
используется
Таким образом, даже несмотря на то, что вы используете deterministic = true
cudnn, некоторые операции не являются детерминированными.
Попробуйте отключить cudnn и посмотрите, не устранена ли проблема.
Комментарии:
1. Я добавил это: «torch.backends.cudnn.enabled=False», но результаты не изменились