Làm cách nào để ngăn chặn dòng chảy phân bổ tổng số bộ nhớ GPU?


282

Tôi làm việc trong một môi trường trong đó các tài nguyên tính toán được chia sẻ, tức là chúng tôi có một vài máy chủ được trang bị một vài GPU Nvidia Titan X mỗi cái.

Đối với các mô hình kích thước nhỏ đến trung bình, 12 GB của Titan X thường đủ để 2 người 3 chạy 3 đào tạo đồng thời trên cùng một GPU. Nếu các mô hình đủ nhỏ để một mô hình duy nhất không tận dụng được tất cả các đơn vị tính toán của GPU, thì điều này thực sự có thể dẫn đến tăng tốc so với chạy một quá trình đào tạo sau một quá trình đào tạo khác. Ngay cả trong trường hợp truy cập đồng thời vào GPU làm chậm thời gian đào tạo cá nhân, vẫn rất tốt để có sự linh hoạt khi có nhiều người dùng đồng thời đào tạo trên GPU.

Vấn đề với TensorFlow là theo mặc định, nó phân bổ toàn bộ lượng bộ nhớ GPU có sẵn khi nó được khởi chạy. Ngay cả đối với một mạng thần kinh hai lớp nhỏ, tôi thấy rằng tất cả 12 GB bộ nhớ GPU đã được sử dụng hết.

Có cách nào để làm cho TensorFlow chỉ phân bổ, giả sử, bộ nhớ GPU 4 GB, nếu ai đó biết rằng điều này là đủ cho một mô hình nhất định?

Câu trả lời:


292

Bạn có thể đặt phân số bộ nhớ GPU được phân bổ khi bạn xây dựng tf.Sessionbằng cách chuyển một tf.GPUOptionsphần của configđối số tùy chọn :

# Assume that you have 12GB of GPU memory and want to allocate ~4GB:
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)

sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

Hoạt per_process_gpu_memory_fractionđộng như một giới hạn trên cứng đối với dung lượng bộ nhớ GPU sẽ được sử dụng bởi quy trình trên mỗi GPU trên cùng một máy. Hiện tại, phân số này được áp dụng thống nhất cho tất cả các GPU trên cùng một máy; không có cách nào để thiết lập điều này trên cơ sở mỗi GPU.


3
Cảm ơn rât nhiều. Thông tin này khá ẩn trong tài liệu hiện tại. Tôi sẽ không bao giờ tự mình tìm thấy nó :-) Nếu bạn có thể trả lời, tôi muốn hỏi thêm hai thông tin bổ sung: 1- Điều này có giới hạn số lượng bộ nhớ từng được sử dụng hay chỉ bộ nhớ được phân bổ ban đầu? (tức là nó vẫn sẽ phân bổ thêm bộ nhớ nếu có nhu cầu cho nó bằng biểu đồ tính toán) 2- Có cách nào để thiết lập điều này trên cơ sở mỗi GPU không?
Fabien C.

15
Lưu ý liên quan: đặt CUDA_VISIBLE_DEVICE để giới hạn TensorFlow cho một GPU duy nhất hoạt động với tôi. Xem acceleware.com/blog/cudavisibledevices-masking-gpus
rd11

2
có vẻ như việc phân bổ bộ nhớ đi một chút so với yêu cầu, e..g tôi yêu cầu per_process_gpu_memory_fraction = 0,0909 trên gpu 24443MiB và quy trình đã tham gia 2627MiB
jeremy_rutman

2
Tôi dường như không thể làm cho nó hoạt động trong mộtMonitoredTrainingSession
Anjum Sayed

2
@jeremy_rutman Tôi tin rằng điều này là do khởi tạo bối cảnh cudnn và cublas. Điều đó chỉ có liên quan nếu bạn đang thực thi các kernel sử dụng các lib đó.
Daniel

186
config = tf.ConfigProto()
config.gpu_options.allow_growth=True
sess = tf.Session(config=config)

https://github.com/tensorflow/tensorflow/issues/1578


13
Đây là chính xác những gì tôi muốn bởi vì trong môi trường nhiều người dùng, rất bất tiện khi chỉ định chính xác dung lượng bộ nhớ GPU để dự trữ trong chính mã.
xuancong84

4
Ngoài ra, nếu bạn đang sử dụng Keras với phụ trợ TF, bạn có thể sử dụng tính năng này và chạy from keras import backend as KK.set_session(sess)để tránh giới hạn bộ nhớ
Oliver

50

Đây là một đoạn trích từ cuốn sách Deep Learning with TensorFlow

Trong một số trường hợp, quy trình chỉ mong muốn phân bổ một tập hợp con của bộ nhớ khả dụng hoặc chỉ phát triển việc sử dụng bộ nhớ theo quy trình cần thiết. TensorFlow cung cấp hai tùy chọn cấu hình trên phiên để kiểm soát điều này. Đầu tiên là allow_growthtùy chọn cố gắng chỉ phân bổ nhiều bộ nhớ GPU dựa trên phân bổ thời gian chạy, nó bắt đầu phân bổ rất ít bộ nhớ và khi các phiên chạy và cần nhiều bộ nhớ GPU hơn, chúng tôi mở rộng vùng bộ nhớ GPU cần thiết bởi TensorFlow quá trình.

1) Cho phép tăng trưởng: (linh hoạt hơn)

config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config, ...)

Phương pháp thứ hai là per_process_gpu_memory_fractiontùy chọn, xác định tỷ lệ của tổng bộ nhớ mà eachGPU hiển thị sẽ được phân bổ. Lưu ý: Không giải phóng bộ nhớ cần thiết, nó thậm chí có thể làm xấu đi sự phân mảnh bộ nhớ khi hoàn tất.

2) Phân bổ bộ nhớ cố định :

Để chỉ phân bổ 40%tổng bộ nhớ của mỗi GPU theo:

config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config, ...)

Lưu ý: Điều đó chỉ hữu ích mặc dù nếu bạn thực sự muốn liên kết lượng bộ nhớ GPU có sẵn trong quy trình TensorFlow.


Theo như câu hỏi của bạn, tùy chọn 2 có thể hữu ích cho bạn. Nói chung, nếu bạn không có nhiều ứng dụng chạy trên GPU và mạng động thì nên sử dụng tùy chọn 'Cho phép tăng trưởng'.
Aniket


19

Tất cả các câu trả lời ở trên giả định thực hiện bằng một sess.run()cuộc gọi, đang trở thành ngoại lệ thay vì quy tắc trong các phiên bản gần đây của TensorFlow.

Khi sử dụng tf.Estimatorkhung (TensorFlow 1.4 trở lên), cách chuyển phân số cho phần được tạo hoàn toàn MonitoredTrainingSessionlà,

opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
trainingConfig = tf.estimator.RunConfig(session_config=conf, ...)
tf.estimator.Estimator(model_fn=..., 
                       config=trainingConfig)

Tương tự trong chế độ Eager (TensorFlow 1.5 trở lên),

opts = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
conf = tf.ConfigProto(gpu_options=opts)
tfe.enable_eager_execution(config=conf)

Chỉnh sửa: 11-04-2018 Ví dụ: nếu bạn đang sử dụng tf.contrib.gan.train, thì bạn có thể sử dụng một cái gì đó tương tự như dưới đây:

tf.contrib.gan.gan_train(........, config=conf)

16

Đối với Tensorflow phiên bản 2.0 và 2.1, hãy sử dụng đoạn mã sau :

 import tensorflow as tf
 gpu_devices = tf.config.experimental.list_physical_devices('GPU')
 tf.config.experimental.set_memory_growth(gpu_devices[0], True)

Đối với các phiên bản trước , đoạn mã sau được sử dụng để làm việc cho tôi:

import tensorflow as tf
tf_config=tf.ConfigProto()
tf_config.gpu_options.allow_growth=True
sess = tf.Session(config=tf_config)

10

Tensorflow 2.0 Beta và (có thể) vượt ra ngoài

API đã thay đổi một lần nữa. Nó có thể được tìm thấy trong:

tf.config.experimental.set_memory_growth(
    device,
    enable
)

Bí danh:

  • tf.compat.v1.config.experimental.set_memory_growth
  • tf.compat.v2.config.experimental.set_memory_growth

Người giới thiệu:

Xem thêm: Tensorflow - Sử dụng GPU : https://www.tensorflow.org/guide/gpu

cho Tensorflow 2.0 Alpha xem: câu trả lời này


8

Bạn có thể dùng

TF_FORCE_GPU_ALLOW_GROWTH=true

trong các biến môi trường của bạn.

Trong mã tenorflow :

bool GPUBFCAllocator::GetAllowGrowthValue(const GPUOptions& gpu_options) {
  const char* force_allow_growth_string =
      std::getenv("TF_FORCE_GPU_ALLOW_GROWTH");
  if (force_allow_growth_string == nullptr) {
    return gpu_options.allow_growth();
}

5

Ổ cắm không biết xấu hổ: Nếu bạn cài đặt Tensorflow hỗ trợ GPU, trước tiên phiên sẽ phân bổ tất cả GPU cho dù bạn đặt nó chỉ sử dụng CPU hay GPU. Tôi có thể thêm mẹo của mình rằng ngay cả khi bạn đặt biểu đồ chỉ sử dụng CPU, bạn cũng nên đặt cấu hình tương tự (như đã trả lời ở trên :)) để ngăn việc chiếm dụng GPU không mong muốn.

Và trong giao diện tương tác như IPython, bạn cũng nên đặt cấu hình đó, nếu không, nó sẽ phân bổ tất cả bộ nhớ và hầu như không dành cho người khác. Điều này đôi khi khó nhận thấy.


3

Đối với Tensorflow 2.0 này giải pháp này làm việc cho tôi. (TF-GPU 2.0, Windows 10, GeForce RTX 2070)

physical_devices = tf.config.experimental.list_physical_devices('GPU')
assert len(physical_devices) > 0, "Not enough GPU hardware devices available"
tf.config.experimental.set_memory_growth(physical_devices[0], True)

1
Tôi đang sử dụng TF-GPU 2.0, Ubuntu 16.04.6, Tesla K80.
azar

@azar - Cảm ơn đã chia sẻ. Đó là vấn đề thú vị tương tự trên cả Ubuntu và Windows. Bằng cách nào đó, tôi luôn nghĩ rằng các vấn đề là khác nhau khi đến gần hơn với phần cứng. Có lẽ điều này đang trở nên ít hơn khi thời gian trôi qua - có thể là một điều tốt.
Sunsetquest

3

Nếu bạn đang sử dụng Tensorflow 2, hãy thử như sau:

config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.compat.v1.Session(config=config)

làm việc cho Tensorflow 2
mobin alhassan

1

tôi đã cố gắng đào tạo unet trên tập dữ liệu giọng nói nhưng vì kích thước hình ảnh lớn, bộ nhớ kết thúc. tôi đã thử tất cả các mẹo ở trên, thậm chí đã thử với kích thước lô == 1, nhưng vẫn không cải thiện. đôi khi phiên bản TensorFlow cũng gây ra các vấn đề về bộ nhớ. thử bằng cách sử dụng

Pip cài đặt tenorflow-gpu == 1.8.0


1

Chà, tôi mới biết về tenorflow, tôi có Geforce 740m hoặc GPU gì đó với ram 2GB, tôi đang chạy loại ví dụ viết tay cho một ngôn ngữ bản địa với dữ liệu đào tạo chứa 38700 hình ảnh và 4300 hình ảnh thử nghiệm và đang cố gắng để có được độ chính xác, nhớ lại, F1 sử dụng mã sau đây như sklearn không mang lại cho tôi các lỗi chính xác. Khi tôi thêm mã này vào mã hiện tại, tôi bắt đầu gặp lỗi GPU.

TP = tf.count_nonzero(predicted * actual)
TN = tf.count_nonzero((predicted - 1) * (actual - 1))
FP = tf.count_nonzero(predicted * (actual - 1))
FN = tf.count_nonzero((predicted - 1) * actual)

prec = TP / (TP + FP)
recall = TP / (TP + FN)
f1 = 2 * prec * recall / (prec + recall)

cộng với mô hình của tôi rất nặng, tôi đoán là tôi đã bị lỗi bộ nhớ sau 147, 148 epoch và sau đó tôi nghĩ tại sao không tạo chức năng cho các tác vụ nên tôi không biết liệu nó có hoạt động theo cách này trong hàng chụcrorflow không, nhưng tôi nghĩ nếu một biến cục bộ là được sử dụng và khi ra khỏi phạm vi nó có thể giải phóng bộ nhớ và tôi đã xác định các yếu tố trên để đào tạo và thử nghiệm trong các mô-đun, tôi có thể đạt được 10000 epoch mà không gặp vấn đề gì, tôi hy vọng điều này sẽ giúp ích ..


Tôi ngạc nhiên về tiện ích của TF mà còn bởi việc sử dụng bộ nhớ. Trên CPU python phân bổ 30 GB hoặc hơn cho một công việc đào tạo trên tập dữ liệu hoa được sử dụng trong các ví dụ TF có thể. Điên.
Eric M

1
# allocate 60% of GPU memory 
from keras.backend.tensorflow_backend import set_session
import tensorflow as tf 
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.6
set_session(tf.Session(config=config))

Câu trả lời được cung cấp đã được gắn cờ để đánh giá là Bài đăng chất lượng thấp. Dưới đây là một số hướng dẫn cho Làm thế nào để tôi viết một câu trả lời tốt? . Câu trả lời được cung cấp này có thể đúng, nhưng nó có thể được hưởng lợi từ một lời giải thích. Mã chỉ trả lời không được coi là câu trả lời "tốt". Từ đánh giá .
Trenton McKinney
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.