Trả lời cho sự kiện TensorFlow Everywhere tại địa phương của bạn ngay hôm nay!
Trang này được dịch bởi Cloud Translation API.
Switch to English

Tối ưu hóa Hiệu suất GPU TensorFlow với Trình biên tập TensorFlow

Tổng quat

Hướng dẫn này dành cho người dùng TensorFlow sử dụng GPU để cải thiện hiệu suất mô hình. Sử dụng TensorFlow Profiler làm công cụ chính để hiểu rõ hơn về hiệu suất, hướng dẫn này sẽ giúp bạn gỡ lỗi khi một hoặc nhiều GPU của bạn không được sử dụng hết. Bạn có thể tìm thấy hướng dẫn bắt đầu nhanh về TensorFlow Profiler trong hướng dẫn TensorFlow Profiler và các cách bổ sung để lấy profile được ghi lại trong phần Tối ưu hóa hiệu suất TensorFlow bằng cách sử dụng hướng dẫn Profiler .

Hãy nhớ rằng việc giảm tải các tính toán sang GPU có thể không phải lúc nào cũng có lợi, đặc biệt là đối với các mô hình nhỏ. Có các chi phí do truyền dữ liệu giữa máy chủ (CPU) và thiết bị (GPU), cũng như các chi phí do độ trễ liên quan khi máy chủ khởi chạy nhân GPU. Hiệu suất tốt đạt được khi máy chủ lưu trữ thành công GPU bằng cách giảm tải đủ công việc.

Quy trình tối ưu hóa hiệu suất

Hướng dẫn này phác thảo cách gỡ lỗi các vấn đề về hiệu suất bắt đầu với một GPU, sau đó chuyển sang một máy chủ duy nhất có nhiều GPU. Bạn nên gỡ lỗi các vấn đề về hiệu suất theo thứ tự này. Ví dụ: nếu bạn đang sử dụng chiến lược phân phối TensorFlow để đào tạo mô hình trên một máy chủ có nhiều GPU và nhận thấy việc sử dụng GPU dưới mức tối ưu, trước tiên bạn nên tối ưu hóa và gỡ lỗi hiệu suất cho 1 GPU, trước khi gỡ lỗi hệ thống đa GPU. Thứ tự được đề xuất như sau:

  1. Tối ưu hóa và gỡ lỗi hiệu suất trên 1 GPU
    1. Kiểm tra xem đường ống đầu vào có bị tắc nghẽn không
    2. Hiệu suất gỡ lỗi của 1 GPU
    3. Bật fp16 và tùy chọn bật XLA
  2. Tối ưu hóa và gỡ lỗi hiệu suất trên máy chủ đơn đa GPU

Là cơ sở để nhận mã hiệu suất trên GPU, hướng dẫn này giả định rằng bạn đang sử dụng tf.function . tf.function . API biên dịch / phù hợp của tf.function sẽ sử dụng tf.function năng tf.function cách tự động. Khi viết một vòng lặp đào tạo tùy chỉnh, hãy tham khảo hướng dẫn này về cách bật tf.function . tf.function .

Các phần tiếp theo thảo luận về các phương pháp tiếp cận được đề xuất cho từng tình huống ở trên để giúp xác định và khắc phục các nút thắt về hiệu suất.

Tối ưu hóa hiệu suất trên 1 GPU

Trong trường hợp lý tưởng, chương trình của bạn phải có hiệu suất sử dụng GPU cao, tối thiểu giao tiếp giữa CPU (máy chủ) với GPU (thiết bị) và không có chi phí từ đường ống đầu vào. Bước đầu tiên để phân tích hiệu suất là lấy hồ sơ cho một mô hình chạy với một GPU.

Trang Tổng quan của TensorFlow Profiler cung cấp ý tưởng về khoảng cách chương trình của bạn so với kịch bản lý tưởng.

TensorFlow Profiler Overview Page

Các số chính cần tìm trên trang tổng quan là:

  1. Thời gian của từng bước là bao nhiêu từ khi thực thi thiết bị thực tế
  2. Phần trăm hoạt động được đặt trên thiết bị so với máy chủ
  3. Có bao nhiêu hạt nhân sử dụng fp16

Đạt được hiệu suất tối ưu có nghĩa là tối đa hóa những con số này trong cả ba trường hợp. Để hiểu sâu hơn về chương trình của mình, bạn cần phải làm quen với trình xem theo dõi TensorFlow Profiler. Các phần bên dưới hiển thị một số mẫu trình xem theo dõi phổ biến mà bạn nên tìm khi chẩn đoán tắc nghẽn hiệu suất.

Dưới đây là hình ảnh của chế độ xem theo dõi mô hình chạy trên 1 GPU. Từ các phần Tensorflow Name ScopeTensorflow Ops , bạn có thể xác định các phần khác nhau của mô hình, chẳng hạn như chuyển tiếp, hàm giảm, tính toán chuyển tiếp / độ dốc lùi và cập nhật trọng số của trình tối ưu hóa. Bạn cũng có thể thấy các hoạt động chạy trên GPU bên cạnh mỗi Luồng , tham chiếu đến luồng CUDA. Mỗi luồng được sử dụng cho các nhiệm vụ cụ thể. Trong dấu vết này, Stream # 118 được sử dụng để khởi chạy tính toán hạt nhân và thiết bị tới các bản sao thiết bị. Luồng # 119 được sử dụng để sao chép từ máy chủ tới thiết bị và Luồng # 120 cho thiết bị lưu trữ bản sao.

image

Dấu vết này cho thấy các đặc điểm chung của một mô hình biểu diễn. Ví dụ: dòng thời gian tính toán GPU ( Luồng # 118 ) có vẻ bận rộn với rất ít khoảng trống. Có các bản sao tối thiểu từ máy chủ đến thiết bị ( Luồng # 119 ) và từ thiết bị sang máy chủ ( Luồng # 120 ), cũng như khoảng cách tối thiểu giữa các bước. Khi bạn chạy TensorFlow Profiler cho chương trình của mình, bạn có thể không thấy những đặc điểm lý tưởng này trong chế độ xem theo dõi của mình. Phần còn lại của hướng dẫn này bao gồm các tình huống phổ biến và cách khắc phục chúng.

Đường ống đầu vào gỡ lỗi

Bước đầu tiên trong gỡ lỗi hiệu suất GPU là xác định xem chương trình của bạn có bị ràng buộc đầu vào hay không. Cách dễ nhất để tìm ra điều này là sử dụng Trình phân tích đường ống đầu vào của TensorFlow Profiler, công cụ này cung cấp tổng quan về thời gian dành cho đường ống đầu vào.

image

Sau đây là những hành động tiềm năng bạn có thể thực hiện nếu quy trình đầu vào của bạn đóng góp đáng kể vào thời gian từng bước:

  • Tham khảo hướng dẫn cụ thể về tf.data để tìm hiểu cách gỡ lỗi đường dẫn đầu vào của bạn.
  • Một cách nhanh chóng khác để kiểm tra xem đường dẫn đầu vào có phải là nút cổ chai hay không là sử dụng dữ liệu đầu vào được tạo ngẫu nhiên mà không cần bất kỳ xử lý trước nào. Đây là một ví dụ về việc sử dụng kỹ thuật này cho mô hình ResNet. Nếu đường dẫn đầu vào là tối ưu, bạn sẽ thấy hiệu suất tương tự với dữ liệu thực và với dữ liệu tổng hợp / ngẫu nhiên được tạo. Chi phí duy nhất trong trường hợp dữ liệu tổng hợp sẽ là do bản sao dữ liệu đầu vào có thể được tìm nạp trước và tối ưu hóa một lần nữa.

Hiệu suất gỡ lỗi của 1 GPU

Có một số yếu tố có thể góp phần vào việc sử dụng GPU thấp. Dưới đây là một số tình huống thường thấy khi nhìn vào trình xem theo dõi và các giải pháp tiềm năng.

Phân tích khoảng cách giữa các bước

Một nhận xét chung khi chương trình của bạn chạy không tối ưu là khoảng cách giữa các bước đào tạo. Trong hình ảnh bên dưới, có một khoảng cách lớn giữa các bước 8 và 9, có nghĩa là GPU không hoạt động trong thời gian đó.

image

Nếu trình xem theo dõi của bạn hiển thị khoảng cách lớn giữa các bước, đây có thể là dấu hiệu cho thấy chương trình của bạn bị ràng buộc đầu vào. Trong trường hợp đó, bạn nên tham khảo phần trước về gỡ lỗi đường dẫn đầu vào của mình nếu bạn chưa làm như vậy. Tuy nhiên, ngay cả với một đường dẫn đầu vào được tối ưu hóa, bạn vẫn có thể thấy khoảng cách giữa phần cuối của bước này và phần bắt đầu của bước khác do tranh chấp luồng CPU. tf.data sử dụng các luồng nền để xử lý đường ống song song. Các luồng này có thể ảnh hưởng đến hoạt động phía máy chủ của GPU xảy ra ở đầu mỗi bước, chẳng hạn như sao chép dữ liệu hoặc lên lịch hoạt động của GPU.

Nếu bạn thấy khoảng trống lớn ở phía máy chủ, nơi lên lịch các hoạt động này trên GPU, bạn có thể đặt biến môi trường TF_GPU_THREAD_MODE=gpu_private . Điều này đảm bảo rằng nhân GPU được khởi chạy từ các luồng chuyên dụng của riêng chúng và không bị xếp hàng sau công việc tf.data .

Khoảng cách giữa các bước cũng có thể do tính toán số liệu, lệnh gọi lại Keras hoặc hoạt động bên ngoài chức năng tf.function chạy trên máy chủ. Các hoạt động này không có hiệu suất tốt bằng các hoạt động bên trong biểu đồ TensorFlow. Ngoài ra, một số hoạt động này chạy trên CPU và sao chép bộ căng qua lại từ GPU.

Nếu sau khi tối ưu hóa đường dẫn đầu vào, bạn vẫn nhận thấy khoảng trống giữa các bước trong trình xem theo dõi, bạn nên xem mã mô hình giữa các bước và xem việc tắt lệnh gọi lại / chỉ số có cải thiện hiệu suất hay không. Một số chi tiết của các hoạt động này cũng có trên trình xem theo dõi (cả thiết bị và máy chủ). Khuyến nghị trong trường hợp này là khấu hao chi phí của các hoạt động này bằng cách thực hiện chúng sau một số bước cố định thay vì mỗi bước. Khi sử dụng phương thức compile trong API tf.keras , việc đặt cờ experimental_steps_per_execution tf.keras sẽ tự động thực hiện việc này. Đối với các vòng huấn luyện tùy chỉnh, hãy sử dụng tf.while_loop . tf.while_loop .

Đạt được mức sử dụng thiết bị cao hơn

Nhân GPU nhỏ và độ trễ khởi chạy nhân máy chủ

Máy chủ sắp xếp các nhân để chạy trên GPU, nhưng có độ trễ (khoảng 20-40 μs) trước khi các nhân thực sự được thực thi trên GPU. Trong trường hợp lý tưởng, máy chủ xếp hàng đợi đủ số nhân trên GPU sao cho GPU dành phần lớn thời gian để thực thi, thay vì đợi máy chủ xếp hàng thêm các nhân.

Trang Tổng quan của TensorFlow Profiler cho biết thời gian GPU không hoạt động do chờ máy chủ khởi chạy các hạt nhân. Trong hình ảnh bên dưới, GPU ở chế độ không hoạt động trong khoảng 10% thời gian của bước chờ các nhân được khởi chạy.

image

Trình xem theo dõi cho cùng một chương trình này hiển thị các khoảng trống nhỏ giữa các hạt nhân khi máy chủ đang bận khởi chạy các hạt nhân trên GPU.

image

Bằng cách khởi chạy nhiều hoạt động nhỏ trên GPU (ví dụ như bổ sung vô hướng), máy chủ có thể không theo kịp GPU. Trang Tensorflow Stats cho cùng một Cấu hình TensorFlow hiển thị 126.224 hoạt động Mul mất 2,77 giây. Do đó, mỗi hạt nhân có kích thước khoảng 21,9 μs, rất nhỏ (cùng khoảng thời gian với độ trễ khởi chạy) và có thể dẫn đến sự chậm trễ khởi chạy hạt nhân máy chủ.

image

Nếu trình xem theo dõi của bạn hiển thị nhiều khoảng trống nhỏ giữa các hoạt động trên GPU như hình trên, bạn có thể:

  • Kết hợp các bộ căng nhỏ và sử dụng các hoạt động được vector hóa hoặc sử dụng kích thước lô lớn hơn để làm cho mỗi hạt nhân được khởi chạy làm được nhiều việc hơn, điều này sẽ khiến GPU bận rộn lâu hơn.
  • Đảm bảo rằng bạn đang sử dụng tf.function để tạo đồ thị TF và không chạy các hoạt động ở chế độ háo hức thuần túy (Sử dụng tf.keras.Model.compile sẽ tự động thực hiện điều này).
  • Cầu chì hạt nhân bằng XLA. Để biết thêm chi tiết, hãy xem phần bên dưới về cách bật XLA để có được hiệu suất cao hơn. Đây là một tính năng thử nghiệm, nhưng dẫn đến hiệu quả sử dụng thiết bị cao.
Tensorflow Op Vị trí

Trang tổng quan về hồ sơ TensorFlow cho bạn biết tỷ lệ phần trăm hoạt động được đặt trên máy chủ so với thiết bị (bạn cũng có thể xác minh vị trí của các hoạt động cụ thể bằng cách xem trình xem theo dõi). Giống như trong hình bên dưới, bạn muốn tỷ lệ hoạt động trên máy chủ lưu trữ rất nhỏ so với thiết bị.

image

Lý tưởng nhất là hầu hết các hoạt động tính toán chuyên sâu nên được đặt trên GPU. Để biết các hoạt động và bộ căng trong mô hình của bạn được gán cho thiết bị nào, hãy đặt tf.debugging.set_log_device_placement(True) làm câu lệnh đầu tiên trong chương trình của bạn. Lưu ý rằng trong một số trường hợp, ngay cả khi bạn chỉ định một op được đặt trên một thiết bị cụ thể, việc triển khai nó có thể ghi đè điều kiện này (ví dụ: tf.unique ). Ngay cả đối với đào tạo GPU đơn, việc chỉ định chiến lược phân phối, chẳng hạn như tf.distribute.OneDeviceStrategy , có thể dẫn đến vị trí xác định hơn của các hoạt động trên thiết bị của bạn.

Một lý do để phần lớn các hoạt động được đặt trên GPU là để ngăn các bản sao bộ nhớ quá mức giữa máy chủ và thiết bị (dự kiến ​​sẽ có các bản sao bộ nhớ cho dữ liệu đầu vào / đầu ra của mô hình giữa máy chủ và thiết bị). Có thể thấy một ví dụ về sao chép quá mức trong chế độ xem theo dõi bên dưới trên các luồng GPU # 167 , # 168# 169 .

image

Những bản sao này đôi khi có thể làm giảm hiệu suất nếu chúng chặn không cho nhân GPU thực thi. Các hoạt động sao chép bộ nhớ trong trình xem theo dõi có thêm thông tin về các hoạt động là nguồn gốc của các tensor được sao chép này, nhưng có thể không phải lúc nào cũng dễ dàng liên kết memCopy với op. Trong những trường hợp này, sẽ rất hữu ích khi nhìn vào các hoạt động gần đó để xem liệu bản sao bộ nhớ có xảy ra ở cùng một vị trí trong mỗi bước hay không.

Nhân hiệu quả hơn trên GPU

Khi việc sử dụng GPU của chương trình của bạn là chấp nhận được, bước tiếp theo là xem xét việc tăng hiệu quả của các nhân GPU bằng cách sử dụng Lõi Tensor hoặc hoạt động hợp nhất.

Sử dụng lõi căng

Các GPU hiện đại có các lõi tensor chuyên biệt có thể cải thiện đáng kể hiệu suất của các hạt nhân đủ điều kiện. Trang thống kê về nhân GPU cho biết những nhân GPU nào đủ tiêu chuẩn Tensor Core và những nhân nào đang sử dụng Tensor Core. Bật fp16 (xem phần Bật chính xác hỗn hợp bên dưới) là một cách để làm cho các hạt nhân Ma trận Chung (GEMM) trong chương trình của bạn (hoạt động matmul) sử dụng Tensor Core.

Để biết các đề xuất chi tiết khác về cách làm cho hạt nhân hiệu quả cho GPU, hãy tham khảo hướng dẫn Hiệu suất học sâu của NVIDIA , bao gồm nhiều kỹ thuật mà bạn có thể thử nghiệm, chẳng hạn như sử dụng định dạng NCHW so với NHWC để thể hiện đầu vào hoặc làm cho kích thước đầu vào trở thành bội số của 8.

Hoạt động hợp nhất

Với tính năng tf.xla.xperimental_compile , TensorFlow có thể kết hợp các hoạt động nhỏ hơn để tạo thành các hạt nhân lớn hơn dẫn đến tăng hiệu suất đáng kể. Chi tiết hơn được thảo luận trong phần Bật XLA bên dưới.

Bật fp16 và XLA

Sau khi làm theo các bước trên, bật độ chính xác hỗn hợp và XLA là hai bước tùy chọn bạn có thể thực hiện để cải thiện hiệu suất hơn nữa. Cách tiếp cận được đề xuất là kích hoạt từng cái một và xác minh rằng lợi ích hiệu suất có như mong đợi.

Kích hoạt độ chính xác hỗn hợp

Hướng dẫn về độ chính xác hỗn hợp TensorFlow cho biết cách bật độ chính xác fp16 trên GPU. Khi nói đến những lợi ích về hiệu suất của fp16, có một số lưu ý cần lưu ý.

Sử dụng hạt nhân fp16 tối ưu

Với fp16 được kích hoạt, các nhân ma trận (GEMM) của chương trình của bạn, sẽ sử dụng phiên bản fp16 tương ứng sử dụng các lõi Tensor. Tuy nhiên, trong một số trường hợp, điều này không xảy ra và bạn không thấy tốc độ tăng như mong đợi khi bật fp16, vì chương trình của bạn rơi vào tình trạng triển khai không hiệu quả.

image

Trang thống kê về nhân GPU hiển thị các hoạt động nào đủ điều kiện cho Tensor Core và những nhân nào thực sự đang sử dụng Tensor Core hiệu quả. Hướng dẫn NVIDIA về hiệu suất học sâu chứa các đề xuất bổ sung về cách tận dụng Lõi Tensor. Ngoài ra, các lợi ích của fp16 cũng sẽ hiển thị trong các hạt nhân trước đây bị giới hạn bộ nhớ, vì bây giờ hoạt động sẽ mất một nửa thời gian.

Tỷ lệ mất mát động so với tĩnh

Chia tỷ lệ tổn thất là cần thiết khi sử dụng fp16 để ngăn chặn dòng chảy dưới do độ chính xác thấp. Có hai loại tỷ lệ tổn thất, động và tĩnh, cả hai đều được giải thích chi tiết hơn trong hướng dẫn Độ chính xác hỗn hợp . Khi cố gắng tối ưu hóa hiệu suất, điều quan trọng cần nhớ là chia tỷ lệ tổn thất động có thể giới thiệu các hoạt động có điều kiện bổ sung chạy trên máy chủ và dẫn đến khoảng trống sẽ hiển thị giữa các bước trong trình xem theo dõi. Mặt khác, tỷ lệ tổn thất tĩnh không có chi phí chung như vậy và có thể là một lựa chọn tốt hơn về mặt hiệu suất với việc bạn cần chỉ định giá trị tỷ lệ tổn thất tĩnh chính xác.

Bật XLA

Là bước cuối cùng để đạt được hiệu suất tốt nhất với một GPU duy nhất, bạn có thể thử nghiệm với việc bật XLA, điều này sẽ hợp nhất các hoạt động và dẫn đến việc sử dụng thiết bị tốt hơn và bộ nhớ thấp hơn. Để biết chi tiết về cách bật XLA trong chương trình của bạn, hãy tham khảo hướng dẫn XLA: Tối ưu hóa Trình biên dịch cho Học máy .

Tối ưu hóa hiệu suất trên Máy chủ đơn đa GPU

API tf.distribute.MirroredStrategy có thể được sử dụng để mở rộng quy mô đào tạo mô hình từ 1 GPU đến nhiều GPU trên một máy chủ duy nhất. Để tìm hiểu thêm về cách thực hiện đào tạo phân tán với Tensorflow, vui lòng tham khảo hướng dẫn Đào tạo phân tán với Keras . Mặc dù việc chuyển đổi từ một GPU sang nhiều GPU lý tưởng nên có thể mở rộng ra khỏi hộp, đôi khi bạn có thể gặp phải các vấn đề về hiệu suất.

Khi chuyển từ đào tạo với một GPU sang nhiều GPU trên cùng một máy chủ, lý tưởng nhất là bạn sẽ thấy hiệu suất mở rộng chỉ với chi phí bổ sung của giao tiếp gradient và tăng mức sử dụng luồng máy chủ. Do chi phí này, bạn sẽ không thấy tốc độ tăng gấp 2 lần chính xác nếu bạn di chuyển từ 1 đến 2 GPU. Chế độ xem theo dõi bên dưới cho thấy một ví dụ về chi phí giao tiếp bổ sung khi đào tạo trên nhiều GPU. Có một số chi phí để nối các gradient, giao tiếp chúng qua các bản sao và chia nhỏ chúng trước khi thực hiện cập nhật trọng lượng.

image

Danh sách kiểm tra sau sẽ giúp bạn đạt được hiệu suất tốt hơn khi tối ưu hóa hiệu suất trong kịch bản đa GPU:

  1. Cố gắng tối đa hóa kích thước lô, điều này sẽ dẫn đến việc sử dụng thiết bị cao hơn và phân bổ chi phí giao tiếp trên nhiều GPU. Sử dụng trình biên dịch bộ nhớ giúp hiểu được chương trình của bạn đã gần đến mức sử dụng bộ nhớ cao nhất. Lưu ý rằng mặc dù kích thước lô cao hơn có thể ảnh hưởng đến sự hội tụ, nhưng điều này thường vượt trội hơn bởi lợi ích hiệu suất.
  2. Khi chuyển từ một GPU sang nhiều GPU, cùng một máy chủ hiện phải xử lý nhiều dữ liệu đầu vào hơn. Vì vậy sau (1) nên kiểm tra lại hoạt động của đường ống đầu vào và đảm bảo rằng nó không bị tắc nghẽn.
  3. Kiểm tra dòng thời gian GPU trong chế độ xem theo dõi chương trình của bạn để xem liệu có lệnh gọi AllReduce liên tục hay không, vì điều này dẫn đến đồng bộ hóa trên tất cả các thiết bị. Trong chế độ xem theo dõi được hiển thị ở trên, AllReduce được thực hiện thông qua hạt nhân NCCL và chỉ có một lệnh gọi NCCL trên mỗi GPU cho các gradient trên mỗi bước.
  4. Kiểm tra các hoạt động sao chép D2H, H2D và D2D không cần thiết và xem liệu chúng có thể được giảm thiểu hay không.
  5. Kiểm tra thời gian bước để đảm bảo mỗi bản sao đang thực hiện công việc giống nhau. Có thể xảy ra trường hợp một GPU (thường là GPU0) bị đăng ký quá mức do máy chủ lưu trữ nhầm lẫn khi đưa thêm công việc lên đó.
  6. Cuối cùng, hãy kiểm tra bước đào tạo trên tất cả các GPU trong chế độ xem theo dõi của bạn để biết bất kỳ hoạt động nào đang thực hiện theo trình tự. Điều này thường xảy ra khi chương trình của bạn bao gồm các phụ thuộc điều khiển từ GPU này sang GPU khác. Hiệu suất gỡ lỗi trong tình huống này đã được giải quyết theo từng trường hợp trong quá khứ. Nếu bạn quan sát thấy hành vi này trong chương trình của mình, hãy gửi sự cố trên Github với hình ảnh về chế độ xem theo dõi của bạn.

Tối ưu hóa Gradient AllReduce

Khi đào tạo với chiến lược đồng bộ, mỗi thiết bị nhận được một phần dữ liệu đầu vào. Sau khi tính toán chuyển tiếp và chuyển tiếp qua mô hình, các gradient được tính toán trên mỗi thiết bị cần được tổng hợp và giảm bớt. AllReduce gradient này xảy ra sau khi tính toán gradient trên mỗi thiết bị và trước khi trình tối ưu hóa cập nhật trọng số mô hình. Đầu tiên, mỗi GPU sẽ nối các gradient trên các lớp mô hình, giao tiếp chúng giữa các GPU bằng tf.distribute.CrossDeviceOps ( tf.distribute.NcclAllReduce là mặc định), sau đó trả về các gradient sau khi giảm mỗi lớp. Trình tối ưu hóa sẽ sử dụng các gradient giảm bớt này để cập nhật trọng lượng của mô hình của bạn. Tốt nhất, quá trình này nên diễn ra cùng một lúc trên tất cả các GPU để ngăn chặn mọi chi phí. Thời gian để Giảm tất cả phải tương đương với:

(number of parameters * 4bytes)/ (communication bandwidth)

Tính toán này hữu ích như một kiểm tra nhanh để hiểu liệu hiệu suất bạn thấy khi chạy công việc đào tạo phân tán có như mong đợi hay bạn cần thực hiện thêm gỡ lỗi hiệu suất. Bạn có thể lấy số lượng tham số trong mô hình của mình từ tf.keras.Model.summary .

Lưu ý rằng mỗi tham số mô hình là 4 byte vì Tensorflow sử dụng fp32 để giao tiếp gradient. Ngay cả khi bạn đã bật fp16, NCCL AllReduce vẫn sử dụng các tham số fp32. Trong tương lai, Tensorflow sẽ hỗ trợ các hoạt động AllReduce bằng cách sử dụng fp16, cũng như kết nối AllReduce gradient để nó chồng chéo với tính toán gradient.

Để thấy được lợi ích của việc mở rộng quy mô, thời gian bước cần phải cao hơn nhiều so với những chi phí chung này. Một cách để đạt được điều này là sử dụng kích thước lô cao hơn vì kích thước lô ảnh hưởng đến thời gian bước, nhưng không ảnh hưởng đến chi phí giao tiếp.

Đề cập đến chủ đề máy chủ GPU

Khi chạy nhiều GPU, công việc của CPU là giữ cho tất cả các thiết bị bận rộn bằng cách khởi chạy hiệu quả các nhân GPU trên các thiết bị. Tuy nhiên, khi có nhiều hoạt động độc lập mà CPU có thể lên lịch trên một GPU, CPU có thể quyết định sử dụng nhiều luồng máy chủ của nó để giữ cho một GPU luôn bận rộn và sau đó khởi chạy nhân trên GPU khác theo một thứ tự không xác định. . Điều này có thể gây ra lệch tỷ lệ hoặc tỷ lệ âm, có thể ảnh hưởng đến hiệu suất.

Trình xem theo dõi bên dưới hiển thị chi phí khi CPU đình trệ nhân GPU khởi chạy không hiệu quả, vì GPU1 không hoạt động và sau đó bắt đầu chạy các hoạt động sau khi GPU2 đã khởi động.

image

Chế độ xem theo dõi cho máy chủ cho thấy máy chủ đang khởi chạy các hạt nhân trên GPU2 trước khi khởi chạy chúng trên GPU1 (lưu ý rằng các hoạt động tf_Compute * bên dưới không phải là chỉ ra các luồng CPU).

image

Nếu bạn thấy nhân GPU đáng kinh ngạc này trong chế độ xem theo dõi chương trình của mình, thì hành động được đề xuất là:

  • Đặt biến môi trường TensorFlow TF_GPU_THREAD_MODE thành gpu_private . Biến môi trường này sẽ yêu cầu máy chủ lưu trữ các luồng riêng tư cho GPU.
  • Theo mặc định, TF_GPU_THREAD_MODE=gpu_private đặt số luồng thành 2, là đủ trong hầu hết các trường hợp. Tuy nhiên, số đó có thể được thay đổi bằng cách đặt biến môi trường TensorFlow TF_GPU_THREAD_COUNT thành số luồng mong muốn.