2017-10-26 30 views
7

Chúng tôi đang chạy các công việc đa GPU trên Tensorflow và đánh giá việc di chuyển từ mô hình dựa trên hàng đợi (sử dụng giao diện string_input_producer) tới API tập dữ liệu Tensorflow mới. Sau này dường như cung cấp một cách dễ dàng hơn để chuyển đổi giữa Train và Validation, đồng thời.Làm thế nào để di chuyển dữ liệu sang nhiều tháp GPU bằng API Dataset của Tensorflow

Đoạn mã bên dưới cho biết cách chúng tôi đang thực hiện việc này.

train_dataset, train_iterator = get_dataset(train_files, batch_size, epochs) 
    val_dataset, val_iterator = get_dataset(val_files, batch_size, epochs) 


    is_validating = tf.placeholder(dtype=bool, shape=()) 
    next_batch = tf.cond(is_validating, 
       lambda: val_iterator.get_next(), 
       lambda: train_iterator.get_next()) 

    validation_tower = self.num_gpus - 1 
    tower_grads = [] 

    for i in range(self.num_gpus): 
     with tf.variable_scope(tf.get_variable_scope(),reuse=(i > 0)): 
      with tf.device('/gpu:%d' % i), tf.name_scope('%s_%d' % ('gpu_', i)) as scope: 
       if i == validation_tower: 
        images, labels = next_batch 
        # Loss funcs snipped out 
       else: 
        images, labels = next_batch 
        # Loss funcs snipped out 

Hàm get_dataset xây dựng tập dữ liệu, đặt chức năng bản đồ và kích thước lô. Nó cũng xây dựng một trình lặp, nhưng không khởi tạo nó. Việc khởi tạo trình lặp lặp lại xảy ra trước khi phiên bắt đầu.

Các boolean is_validating được cung cấp trong khi phiên giao dịch đang chạy, và cứ vài bước mà chúng tôi vượt qua is_validating như thật thông qua một feed_dict để sử dụng số liệu xác nhận

Câu hỏi tôi có là:

phép nói rằng tôi có 8 gpus, vì vậy chúng tôi chạy đào tạo trên 7 GPU. Liệu Iterator có tăng tốc từ cùng một điểm cho mỗi 7 GPU này, do đó cung cấp tất cả 7 GPU có cùng dữ liệu không?

Trả lời

7

Hiện nay có ba lựa chọn chính, trong đó có khả năng sử dụng khác nhau và hoạt động thương mại-offs:

  1. Trong Dataset.batch() biến đổi, tạo ra một lô lớn duy nhất có chứa các ví dụ cho tất cả các GPU của bạn. Sau đó, sử dụng tf.split(..., self.num_gpus) trên đầu ra của Iterator.get_next() để tạo các phân đoạn phụ cho mỗi GPU. Đây có lẽ là cách tiếp cận dễ dàng nhất, nhưng nó đặt sự chia tách trên con đường quan trọng.

  2. Trong phép biến đổi Dataset.batch(), hãy tạo một lô nhỏ được định kích thước cho một GPU. Sau đó, gọi Iterator.get_next() một lần trên mỗi GPU để nhận được nhiều lô khác nhau. (Ngược lại, trong mã hiện tại của bạn, cùng một giá trị của next_batch được gửi tới mỗi GPU, có thể không phải là những gì bạn muốn xảy ra.)

  3. Tạo nhiều trình lặp, một trên mỗi GPU. Phân phát dữ liệu bằng cách sử dụng Dataset.shard() sớm trong đường ống (ví dụ: trong danh sách tệp nếu tập dữ liệu của bạn bị phân đoạn). Lưu ý rằng phương pháp này sẽ tiêu thụ nhiều tài nguyên trên máy chủ, vì vậy bạn có thể cần phải quay xuống bất kỳ kích thước bộ đệm và/hoặc mức độ xử lý song song

Lưu ý rằng tf.data đường ống hiện chạy trên CPU mà thôi, và quan trọng khía cạnh của một đường ống hiệu quả là dàn dựng đầu vào đào tạo của bạn với GPU trong khi bước trước đó vẫn đang chạy. Xem mã số TensorFlow CNN benchmarks để biết cách hiển thị dữ liệu hiệu quả cho GPU. Chúng tôi hiện đang làm việc để thêm hỗ trợ này vào API tf.data trực tiếp.

+0

Cảm ơn, @mrry! Rất hữu ích và chi tiết. Đây là một câu hỏi khác cho bạn: Trong phương pháp tiếp cận dựa trên hàng đợi hiện tại của chúng tôi (tf.train.string_input_producer), chúng tôi có một hàng đợi trên mỗi GPU và mỗi Hàng đợi có một bản sao của toàn bộ tập dữ liệu. Mỗi hàng đợi được xáo trộn và công việc chạy vô hạn trong tập dữ liệu cho một số bước cố định. Chúng tôi đã thử phương pháp Dataset, Iterator trên mỗi GPU tương tự và nó hoạt động. Tuy nhiên, sự khác biệt chính mà chúng tôi nhận thấy là số lượng các ví dụ được xử lý. Trước đây chúng tôi xử lý khoảng 200 ví dụ mỗi giây và sau đó khoảng 20 ví dụ, sau đó khoảng 10X thông lượng thấp hơn (tiếp tục ..) – wrecktangle

+0

Đây có phải là do string_input_producers đang chạy trên GPU không? Có một phương pháp Dataset, Iterator có thể cho phép loại thông lượng này không?Bất kỳ đề xuất nào khác về cách tiếp cận hiện tại của chúng tôi cũng sẽ hữu ích. – wrecktangle

+0

Tôi đang cố gắng để thực hiện giải pháp này vào mã điểm chuẩn, nhưng có vẻ như rất khó khăn không phải vì tf.Dataset nhưng vì các chủ đề để có được dữ liệu. Điều duy nhất tôi thay đổi là một chức năng tf.cond bên trong minibatch nhưng mã stucks mãi mãi trên self.cond.wait() – chrisrn

Các vấn đề liên quan