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)