Ich bin auf ein CUDA-Speicherproblem gestoßen. Dies geschieht beim Ableiten eines PyTorch-Modells. Die Eingabedaten haben eine feste Größe ([128, 1, 512]).
Wenn ich nur eine Vorhersage für eine Datei mache, schlägt die Schlussfolgerung fehl. Ich bekomme diese Werte zurück:
  pData.size(): torch.Size([128, 1, 512])
    torch.cuda.memory_allocated(): 357376
    torch.cuda.memory_reserved(): 2097152
Und in dem Fall, dass ich einen Dateiordner vorhersage, ist die Schlussfolgerung erfolgreich. Ich bekomme diese Werte:
    pData.size(): torch.Size([128, 1, 512])
    torch.cuda.memory_allocated(): 358400
    torch.cuda.memory_reserved(): 44040192
Dies ist der Fehler, den ich erhalte, wenn ich eine einzelne Vorhersage für eine Datei mache:
  ...
    x.size: torch.Size([128, 1, 512])
    x.size: torch.Size([128, 1, 512])
    x: tensor([[[0.54997, 0.52163, 0.19563,  ..., 0.34677, 0.23625, 0.21865]],
    ...
    RuntimeError: CUDA out of memory. Tried to allocate 20.00 MiB (GPU 0; 7.78 GiB total capacity; 10.22 MiB already allocated; 1.19 MiB free; 22.00 MiB reserved in total by PyTorch)
Und hier ist die Ausgabe, wenn ich alle Dateien in einem Ordner durchsuche:
  ...
    x.size: torch.Size([128, 1, 512])
    x.size: torch.Size([128, 1, 512])
    x: tensor([[[0.4228, 0.4436, 0.3818,  ..., 0.1387, 0.1879, 0.1545]],
    ...
    Y_pred.shape: (4986,) Y.shape: (4986,)
Der zur Vorhersage aller Dateien in einem Ordner verwendete Code lautet:
  model = UC_Model(pModel_filepath="/mnt/confiance/common/UC_Data_Folder/UC_Anomaly_Detection/models/trained_perceiver/best_model_spectra")
    (X, Y, X_val, Y_val), (l_data_X, l_data_Y) = model.prepareData(
        pDataPath="/mnt/confiance/common/UC_Data_Folder/UC_Anomaly_Detection/Dataset/test_bench_data/")
    X = np.transpose(X, (0, 2, 1))
    X_val = np.transpose(X, (0, 2, 1))
    print("X.shape: ", X.shape)
    print("Y.shape: ", Y.shape)
    X_LENGTH = len(X) 
    with torch.no_grad():
        correct = 0
        total = 0
        loss = 0
        Y_pred = np.zeros(np.shape(Y))
        for i in range(X_LENGTH // BATCH_SIZE):
            x = torch.from_numpy(
                X[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]
            ).float().to(DEVICE)
            print("x.size: ", x.size())
            print("x.size: ", x.size())
            y = torch.from_numpy(
                Y[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]
            ).long().to(DEVICE)
            x = x.to(DEVICE)
            y_ = model(x)
            y_ = y_.cpu().argmax(dim=-1)
            total += len(y_)
            print("y_.size: ", y_.size(), " y.size(): ", y.size())
            correct += (y_ == y.cpu()).sum().item()
            Y_pred[i * BATCH_SIZE:(i + 1) * BATCH_SIZE] = y_
    plot_confusion_matrix(Y, Y_pred, anomaly_list)
    print("Y_pred.shape: ", Y_pred.shape, "Y.shape: ", Y.shape)
Und der Code zum Verarbeiten einer einzelnen Datei lautet:
 def UC_computeInference(pAiModel,pDictParams):
        pNbData=pDictParams['nbData']
        pClasses=pDictParams['classes']
        pDataPathList=pDictParams['dataPathList']
        pDataProd=pDictParams['dataProd']
        pRepertProd=pDictParams['repertProd']
        pSauvegarde=pDictParams['backup']=="oui"
        pListObjets=pDictParams['objets']
        pDataList=pDictParams['dataList']
        listInferError=[]
        x_test=[]
        y_pred=[]
        for i in range(pNbData):
            dataPreprocessed=pAiModel.prepareData(pDataPathList[i])
            prediction=pAiModel(dataPreprocessed)
In allen Fällen ist dies die Funktion, die zum Initialisieren und Aufrufen des Modells verwendet wird:
  class UC_Model:
        #-------------------------------------------------------------------------------
        ## Fonction d'initialisation du modèle
        # @param pModel_filepath : chemin d'accès du modèle fourni
        # def __init__(self, pModelpath, pModel_filepath, pParams_filepath="perceiver_params.json"):
        def __init__(self, pModel_filepath):
    
            self.name="UC_Anomaly_Detection"  # le nom du sous-répertoire du use case dans le répertoire des Use Case MODEL_BASE
            self.resPredictionsCibles=[]
            self.resPredictionsSamples=[]
            self.inferenceCible=True
    
            # Initialize model
            # self.model = create_perceiver_model()
    
            # Load model
            # /mnt/confiance/common/UC_Data_Folder/UC_Anomaly_Detection/models/trained_perceiver/best_model_spectra 
            self.model = torch.load(pModel_filepath)
    
        def to_tensor(self, X, Y, i):
            x = torch.from_numpy(
                X[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]
            ).float().to(DEVICE)
            print("x.size: ", x.size()) # x.size:  torch.Size([128, 512, 1]) alors qu'il faut x.size:  torch.Size([128, 1, 512])
            x = x.permute(0, 2, 1) # C'est pas grave, on permute 
            print("after permutting: ")
            print("x.size: ", x.size())
            y = torch.from_numpy(
                Y[i * BATCH_SIZE:(i + 1) * BATCH_SIZE]
            ).long().to(DEVICE)
            x = x.to(DEVICE)
            
            return x, y
    
        ## Fonction d'appel du modèle
        # @param pData : données/samples à traiter
        # @return resultat d'inférence
        def __call__(self, pData):
            print("pData.size(): ", pData.size())
            print("torch.cuda.memory_allocated(): ", torch.cuda.memory_allocated())
            print("torch.cuda.memory_reserved(): ", torch.cuda.memory_reserved())
            # Run the Perceiver on the model
            z = self.model.perceiver(pData)
        
            # Pass through linear layers
            z = self.model.linear1(z)
            z = z.mean(dim=0)
            z = self.model.linear2(z)
            return F.log_softmax(z, dim=-1)