tensorflow.js GPU 崩溃
tensorflow.js GPU crashing
我的模型获取图像并计算出某个值,输入层是裁剪层,从图像的顶部和底部移除一些像素。该模型运行良好,但是当我更改裁剪层的设置时,例如,从顶部移除 25 个像素而不是 75 个像素,浏览器 window (chrome) 闪烁并输出以下错误:
注意:在出现上述错误之前,它会打印出以下消息 Couldn't parse line number in error
,后跟似乎是 GLSL 代码的内容。
如果我完全删除裁剪层,也会出现同样的错误。
我使用的是 tfjs v3.8.0,但也使用 v2.0.0 进行了测试,结果相似。这是我的模型:
const model = tf.sequential();
// Cropping Layer
model.add(
tf.layers.cropping2D({
// If I change 75 to anything below 50, it crashes before completing the first epoch,
// If this layer is removed, it crashes almost immediately after training starts
cropping: [
[75, 25],
[0, 0]
],
// image height, width, depth
inputShape: [160, 320, 3]
})
);
model.add(
tf.layers.conv2d({
filters: 16,
kernelSize: [3, 3],
strides: [2, 2],
activation: 'relu',
})
);
model.add(
tf.layers.maxPool2d({
poolSize: [2, 2]
})
);
model.add(
tf.layers.conv2d({
filters: 32,
kernelSize: [3, 3],
strides: [2, 2],
activation: 'relu'
})
);
model.add(
tf.layers.maxPool2d({
poolSize: [2, 2]
})
);
model.add( tf.layers.flatten());
model.add( tf.layers.dense({ units: 1024, activation: 'relu' }));
model.add( tf.layers.dropout({ rate: 0.25 }));
model.add( tf.layers.dense({ units: 128, activation: 'relu' }));
model.add( tf.layers.dense({ units: 1, activation: 'linear' }));
model.compile({
optimizer: 'adam',
loss: 'meanSquaredError',
metrics: [
'accuracy',
],
});
我做错了什么吗?
丢失 GL 上下文意味着您可能 运行 GPU 内存不足
与模型实际需要的相比,WebGL 后端具有巨大的开销
通过强制 GL 内存清理而不是将其保留为默认值,您可能会更进一步,但这是有代价的(它确实会显着减慢速度)
tf.ENV.set('WEBGL_DELETE_TEXTURE_THRESHOLD', 0);
正如@vladimir-mandic 所建议的那样,最终问题确实是 GPU 运行 内存不足。但是将 WEBGL_DELETE_TEXTURE_THRESHOLD
设置为零对我的情况没有帮助。
我花了一些时间来验证这一点,因为它发生在批次之间,我无法通过 tf.memory()
在 batchEnd
跟踪它,因为在回调中内存已经被释放或者 GPU 会在达到那个点之前崩溃。我最终做了两件事来克服这个问题:
- 减小图像尺寸: 裁剪层有助于不达到 'out of memory' 状态,因此删除它或减少裁剪的像素数会导致应用程序坠毁。但由于它也分配张量,我决定在将它们输入模型之前通过 canvas 操作调整图像大小。
- 减少 batchSize: 我一直在使用默认的 batchSize 32,直到我减少它,我才开始注意到崩溃会消失,这导致我调查了
model.fitDataset
的内部结构,这就是我发现批次之间内存消耗过多的原因。
正如@vladimir-mandic 推荐的那样,将 WEBGL_DELETE_TEXTURE_THRESHOLD
设置为 0 应该也有助于缓解这个问题,但我没有注意到对我的情况有任何显着影响,所以我最终没有使用它。
我的模型获取图像并计算出某个值,输入层是裁剪层,从图像的顶部和底部移除一些像素。该模型运行良好,但是当我更改裁剪层的设置时,例如,从顶部移除 25 个像素而不是 75 个像素,浏览器 window (chrome) 闪烁并输出以下错误:
注意:在出现上述错误之前,它会打印出以下消息 Couldn't parse line number in error
,后跟似乎是 GLSL 代码的内容。
如果我完全删除裁剪层,也会出现同样的错误。
我使用的是 tfjs v3.8.0,但也使用 v2.0.0 进行了测试,结果相似。这是我的模型:
const model = tf.sequential();
// Cropping Layer
model.add(
tf.layers.cropping2D({
// If I change 75 to anything below 50, it crashes before completing the first epoch,
// If this layer is removed, it crashes almost immediately after training starts
cropping: [
[75, 25],
[0, 0]
],
// image height, width, depth
inputShape: [160, 320, 3]
})
);
model.add(
tf.layers.conv2d({
filters: 16,
kernelSize: [3, 3],
strides: [2, 2],
activation: 'relu',
})
);
model.add(
tf.layers.maxPool2d({
poolSize: [2, 2]
})
);
model.add(
tf.layers.conv2d({
filters: 32,
kernelSize: [3, 3],
strides: [2, 2],
activation: 'relu'
})
);
model.add(
tf.layers.maxPool2d({
poolSize: [2, 2]
})
);
model.add( tf.layers.flatten());
model.add( tf.layers.dense({ units: 1024, activation: 'relu' }));
model.add( tf.layers.dropout({ rate: 0.25 }));
model.add( tf.layers.dense({ units: 128, activation: 'relu' }));
model.add( tf.layers.dense({ units: 1, activation: 'linear' }));
model.compile({
optimizer: 'adam',
loss: 'meanSquaredError',
metrics: [
'accuracy',
],
});
我做错了什么吗?
丢失 GL 上下文意味着您可能 运行 GPU 内存不足
与模型实际需要的相比,WebGL 后端具有巨大的开销
通过强制 GL 内存清理而不是将其保留为默认值,您可能会更进一步,但这是有代价的(它确实会显着减慢速度)
tf.ENV.set('WEBGL_DELETE_TEXTURE_THRESHOLD', 0);
正如@vladimir-mandic 所建议的那样,最终问题确实是 GPU 运行 内存不足。但是将 WEBGL_DELETE_TEXTURE_THRESHOLD
设置为零对我的情况没有帮助。
我花了一些时间来验证这一点,因为它发生在批次之间,我无法通过 tf.memory()
在 batchEnd
跟踪它,因为在回调中内存已经被释放或者 GPU 会在达到那个点之前崩溃。我最终做了两件事来克服这个问题:
- 减小图像尺寸: 裁剪层有助于不达到 'out of memory' 状态,因此删除它或减少裁剪的像素数会导致应用程序坠毁。但由于它也分配张量,我决定在将它们输入模型之前通过 canvas 操作调整图像大小。
- 减少 batchSize: 我一直在使用默认的 batchSize 32,直到我减少它,我才开始注意到崩溃会消失,这导致我调查了
model.fitDataset
的内部结构,这就是我发现批次之间内存消耗过多的原因。
正如@vladimir-mandic 推荐的那样,将 WEBGL_DELETE_TEXTURE_THRESHOLD
设置为 0 应该也有助于缓解这个问题,但我没有注意到对我的情况有任何显着影响,所以我最终没有使用它。