+ nb_correct += correct * reverse_correct
+
+ return nb_correct
+
+ ###############################################################
+
+ def generate_quizzes(self, nb, model_for_generation, min_ave_seq_logproba):
+ c_quizzes = torch.empty(
+ nb, self.train_w_quizzes.size(1), device=self.device, dtype=torch.int64
+ )
+
+ ar_mask_prompt = torch.zeros(c_quizzes.size(), device=self.device)
+ ar_mask_prompt[:, : ar_mask_prompt.size(1) // 2 + 1] = 1
+ ar_mask_solve = 1 - ar_mask_prompt
+ seq_logproba = torch.empty(ar_mask_prompt.size(0), device=self.device)
+
+ # bracketing of the temperature to get the target logproba if
+ # min_ave_seq_logproba is not None
+
+ temperature = 2
+ d_temperature = 1 / 3
+
+ while True:
+ seq_logproba[...] = 0
+
+ masked_inplace_autoregression(
+ model=model_for_generation,
+ batch_size=self.batch_size,
+ input=c_quizzes,
+ ar_mask=ar_mask_prompt,
+ seq_logproba=seq_logproba,
+ temperature=temperature,
+ deterministic_synthesis=False,
+ # progress_bar_desc="sampling c_quizzes",
+ device=self.device,
+ )
+
+ ave_seq_logproba = seq_logproba.mean()
+
+ masked_inplace_autoregression(
+ model=model_for_generation,
+ batch_size=self.batch_size,
+ input=c_quizzes,
+ ar_mask=ar_mask_solve,
+ seq_logproba=seq_logproba,
+ temperature=temperature,
+ deterministic_synthesis=True,
+ # progress_bar_desc="sampling c_quizzes",
+ device=self.device,
+ )
+
+ # If we do not have target logprobs, get out now
+ if min_ave_seq_logproba is None:
+ break
+
+ # Oh man that's ugly
+ if ave_seq_logproba < min_ave_seq_logproba:
+ if d_temperature > 0:
+ d_temperature *= -1 / 3
+ temperature += d_temperature
+ elif ave_seq_logproba > min_ave_seq_logproba * 0.99:
+ if d_temperature < 0:
+ d_temperature *= -1 / 3
+ temperature += d_temperature
+ else:
+ break
+
+ self.logger(f"changing temperature to {temperature}")
+
+ return c_quizzes, seq_logproba.mean()
+
+ ######################################################################