Khả năng tương thích với phiên bản TensorFlow

Tài liệu này dành cho những người dùng cần khả năng tương thích ngược trên các phiên bản khác nhau của TensorFlow (đối với mã hoặc dữ liệu) và dành cho các nhà phát triển muốn sửa đổi TensorFlow trong khi vẫn duy trì khả năng tương thích.

Phiên bản ngữ nghĩa 2.0

TensorFlow sau Semantic Versioning 2.0 ( semver ) cho API công cộng của nó. Mỗi phiên bản phát hành TensorFlow có dạng MAJOR.MINOR.PATCH . Ví dụ, TensorFlow phiên bản 1.2.3 có MAJOR phiên bản 1, MINOR phiên bản 2, và PATCH phiên bản 3. Những thay đổi cho mỗi số có nghĩa sau đây:

  • CHỦ YẾU: có khả năng thay đổi ngược không tương thích. Mã và dữ liệu đã hoạt động với bản phát hành chính trước đó sẽ không nhất thiết phải hoạt động với bản phát hành mới. Tuy nhiên, trong một số trường hợp, các đồ thị và điểm kiểm tra TensorFlow hiện có có thể được chuyển sang bản phát hành mới hơn; thấy Sự phù hợp của đồ thị và các điểm kiểm tra để biết chi tiết về khả năng tương thích dữ liệu.

  • NHỎ: ngược tính năng tương thích, cải thiện tốc độ, vv Mã và dữ liệu mà làm việc với một phiên bản nhỏ trước trong đó chỉ phụ thuộc vào các API công cộng phi thực nghiệm sẽ tiếp tục làm việc không thay đổi. Để biết chi tiết trên là gì và không phải là API công cộng, xem gì được bao phủ .

  • PATCH: sửa lỗi tương thích ngược.

Ví dụ, phiên bản 1.0.0 giới thiệu những thay đổi ngược không tương thích từ phiên bản 0.12.1. Tuy nhiên, phiên bản 1.1.1 đã tương thích ngược với phiên bản 1.0.0.

Những gì được bảo hiểm

Chỉ các API công khai của TensorFlow tương thích ngược trên các phiên bản nhỏ và vá lỗi. Các API công khai bao gồm

  • Tất cả các tài liệu Python chức năng và các lớp học trong tensorflow mô-đun và các môđun con của nó, ngoại trừ

    • Những biểu tượng cá nhân: bất kỳ chức năng, lớp, vv có tên bắt đầu với _
    • Thực nghiệm và tf.contrib biểu tượng, nhìn thấy dưới đây để biết chi tiết.

    Lưu ý rằng mã trong examples/tools/ thư mục là không thể truy cập thông qua các tensorflow Python mô-đun và do đó không thuộc phạm vi bảo đảm tính tương thích.

    Nếu một biểu tượng có sẵn thông qua tensorflow Python mô-đun hoặc submodules của nó, nhưng không được ghi nhận, sau đó nó không được coi là một phần của API công cộng.

  • API tương thích (bằng Python, các tf.compat mô-đun). Tại các phiên bản chính, chúng tôi có thể phát hành các tiện ích và thiết bị đầu cuối bổ sung để giúp người dùng chuyển đổi sang phiên bản chính mới. Các ký hiệu API này không được dùng nữa và không được hỗ trợ (nghĩa là chúng tôi sẽ không thêm bất kỳ tính năng nào và chúng tôi sẽ không sửa các lỗi ngoài việc sửa các lỗ hổng bảo mật), nhưng chúng nằm trong sự đảm bảo về khả năng tương thích của chúng tôi.

  • Các C API .

  • Các tệp đệm giao thức sau:

Những gì không được bảo hiểm

Một số phần của TensorFlow có thể thay đổi theo những cách không tương thích ngược vào bất kỳ thời điểm nào. Bao gồm các:

  • API thử nghiệm: Để tạo điều kiện phát triển, chúng tôi miễn một số biểu tượng API đánh dấu rõ ràng như thực nghiệm từ những bảo đảm tính tương thích. Đặc biệt, những điều sau đây không nằm trong bất kỳ đảm bảo tương thích nào:

    • bất kỳ biểu tượng trong tf.contrib mô-đun hoặc submodules của nó;
    • bất kỳ biểu tượng (mô-đun, chức năng, tranh luận, bất động sản, lớp học, hoặc không đổi) có tên chứa experimental hoặc Experimental ; hoặc
    • bất kỳ biểu tượng nào có tên đủ điều kiện bao gồm một mô-đun hoặc lớp tự nó là thử nghiệm. Điều này bao gồm các lĩnh vực và submessages của bất kỳ đệm giao thức gọi là experimental .
  • Ngôn ngữ khác: API TensorFlow bằng các ngôn ngữ khác hơn Python và C, chẳng hạn như:

  • Chi tiết về ops hợp: Nhiều chức năng công cộng bằng Python mở rộng đến một số ops nguyên thủy trong đồ thị, và những chi tiết này sẽ là một phần của bất kỳ đồ thị lưu vào đĩa như GraphDef s. Các chi tiết này có thể thay đổi đối với các bản phát hành nhỏ. Đặc biệt, các bài kiểm tra hồi quy để kiểm tra sự khớp chính xác giữa các biểu đồ có khả năng bị phá vỡ trong các bản phát hành nhỏ, mặc dù hành vi của biểu đồ sẽ không thay đổi và các điểm kiểm tra hiện có vẫn hoạt động.

  • Floating điểm chi tiết số: Các giá trị dấu chấm động cụ thể tính bằng cách ops có thể thay đổi bất cứ lúc nào. Người dùng chỉ nên dựa vào độ chính xác gần đúng và độ ổn định số, không dựa vào các bit cụ thể được tính toán. Các thay đổi đối với công thức số trong các bản phát hành nhỏ và vá sẽ dẫn đến độ chính xác tương đương hoặc được cải thiện, với lưu ý rằng trong máy học, độ chính xác được cải thiện của các công thức cụ thể có thể làm giảm độ chính xác của hệ thống tổng thể.

  • Số ngẫu nhiên: Những con số ngẫu nhiên cụ thể tính toán có thể thay đổi bất cứ lúc nào. Người dùng chỉ nên dựa vào các phân phối gần đúng và cường độ thống kê, chứ không phải các bit cụ thể được tính toán. Xem thế hệ số ngẫu nhiên dẫn để biết chi tiết.

  • Version nghiêng trong phân phối Tensorflow: Chạy hai phiên bản khác nhau của TensorFlow trong một cụm duy nhất là không được hỗ trợ. Không có đảm bảo nào về khả năng tương thích ngược của giao thức dây.

  • Bugs: Chúng tôi bảo lưu quyền thực hiện các hành vi ngược không tương thích (mặc dù không phải API) thay đổi nếu việc triển khai hiện nay được chia rõ ràng, có nghĩa là, nếu nó mâu thuẫn với tài liệu hướng dẫn hoặc nếu một nổi tiếng và hành vi dự định cũng xác định không được thực hiện đúng cách do cho một lỗi. Ví dụ: nếu trình tối ưu hóa tuyên bố triển khai một thuật toán tối ưu hóa nổi tiếng nhưng không khớp với thuật toán đó do lỗi, thì chúng tôi sẽ sửa chữa trình tối ưu hóa. Bản sửa lỗi của chúng tôi có thể phá vỡ mã dựa trên hành vi hội tụ sai. Chúng tôi sẽ ghi nhận những thay đổi như vậy trong ghi chú phát hành.

  • Không sử dụng API: Chúng tôi bảo lưu quyền thực hiện các thay đổi ngược không tương thích với các API mà chúng tìm thấy không có sử dụng tài liệu (bằng cách thực hiện kiểm toán việc sử dụng TensorFlow thông qua tìm kiếm GitHub). Trước khi thực hiện bất kỳ thay đổi như vậy, chúng tôi sẽ công bố ý định của chúng tôi để thực hiện thay đổi trên thông báo @ mailing list , cung cấp hướng dẫn làm thế nào để giải quyết bất kỳ vỡ (nếu có), và chờ cho hai tuần để cung cấp cho cộng đồng của chúng tôi một cơ hội để chia sẻ thông tin phản hồi của họ .

  • Hành vi lỗi: Chúng tôi có thể thay thế lỗi với hành vi không báo lỗi. Ví dụ: chúng tôi có thể thay đổi một hàm để tính toán kết quả thay vì đưa ra lỗi, ngay cả khi lỗi đó đã được ghi lại. Chúng tôi cũng có quyền thay đổi nội dung của thông báo lỗi. Ngoài ra, loại lỗi có thể thay đổi trừ khi loại ngoại lệ cho một điều kiện lỗi cụ thể được chỉ định trong tài liệu.

Khả năng tương thích của SavedModels, đồ thị và điểm kiểm tra

SavedModel là định dạng tuần tự hóa được ưu tiên sử dụng trong các chương trình TensorFlow. SavedModels chứa hai phần: Một hoặc nhiều đồ mã hóa như GraphDefs và Checkpoint. Các biểu đồ mô tả luồng dữ liệu của các hoạt động sẽ được chạy và các điểm kiểm tra chứa các giá trị tensor đã lưu của các biến trong biểu đồ.

Nhiều người dùng TensorFlow tạo SavedModels, tải và thực thi chúng với bản phát hành sau của TensorFlow. Phù hợp với semver , SavedModels bằng văn bản với một phiên bản của TensorFlow có thể được nạp và đánh giá với một phiên bản sau này của TensorFlow với việc phát hành lớn như vậy.

Chúng tôi đưa ra đảm bảo bổ sung cho SavedModels được hỗ trợ. Chúng tôi gọi một SavedModel được tạo ra chỉ sử dụng không bị phản đối, không thực nghiệm, các API không tương thích trong TensorFlow phiên bản chính N một SavedModel được hỗ trợ trong phiên bản N . Bất kỳ SavedModel được hỗ trợ trong phiên bản chính TensorFlow N có thể được nạp và thực hiện với TensorFlow phiên bản chính N+1 . Tuy nhiên, chức năng cần thiết để xây dựng hoặc sửa đổi một mô hình như vậy có thể không còn khả dụng nữa, vì vậy đảm bảo này chỉ áp dụng cho SavedModel chưa được sửa đổi.

Chúng tôi sẽ cố gắng duy trì khả năng tương thích ngược lâu nhất có thể, để các tệp được tuần tự hóa có thể sử dụng được trong thời gian dài.

Khả năng tương thích GraphDef

Đồ thị được đăng thông qua GraphDef giao thức đệm. Để tạo điều kiện thay đổi ngược không tương thích với đồ thị, mỗi GraphDef có một số phiên bản riêng biệt từ phiên bản TensorFlow. Ví dụ, GraphDef phiên bản 17 bị phản đối các inv op ủng hộ reciprocal . Các ngữ nghĩa là:

  • Mỗi phiên bản của TensorFlow hỗ trợ một khoảng thời gian GraphDef phiên bản. Khoảng thời gian này sẽ không đổi trên các bản vá lỗi và sẽ chỉ tăng lên trên các bản phát hành nhỏ. Gỡ bỏ hỗ trợ cho một GraphDef phiên bản sẽ chỉ xảy ra đối với một thông cáo chính của TensorFlow (và chỉ phù hợp với sự hỗ trợ phiên bản đảm bảo cho SavedModels).

  • Biểu đồ vừa tạo được giao nhiệm vụ mới nhất GraphDef số phiên bản.

  • Nếu một phiên bản nhất định của TensorFlow hỗ trợ GraphDef phiên bản của một đồ thị, nó sẽ được tải và đánh giá với hành vi tương tự như các phiên bản TensorFlow sử dụng để tạo ra nó (trừ nổi chi tiết điểm số và số ngẫu nhiên như đã nêu ở trên), không phụ thuộc vào chính phiên bản của TensorFlow. Cụ thể, GraphDef tương thích với tệp điểm kiểm tra trong một phiên bản của TensorFlow (chẳng hạn như trường hợp trong SavedModel) sẽ vẫn tương thích với điểm kiểm tra đó trong các phiên bản tiếp theo, miễn là GraphDef được hỗ trợ.

    Lưu ý rằng điều này chỉ áp dụng cho đồ thị tuần tự trong GraphDefs (và SavedModels): mà đọc một trạm kiểm soát có thể không có khả năng đọc các điểm kiểm tra được tạo ra bởi cùng một mã chạy một phiên bản khác của TensorFlow.

  • Nếu GraphDef trên ràng buộc được tăng lên X trong một (nhỏ) phát hành, sẽ có ít nhất sáu tháng trước khi bị ràng buộc thấp được tăng lên X. Ví dụ (chúng tôi đang sử dụng số phiên bản giả ở đây):

    • TensorFlow 1.2 có thể hỗ trợ GraphDef phiên bản 4-7.
    • TensorFlow 1.3 có thể thêm GraphDef phiên bản 8 và hỗ trợ các phiên bản 4-8.
    • Ít nhất sáu tháng sau, TensorFlow 2.0.0 có thể ngừng hỗ trợ cho các phiên bản 4 đến 7, chỉ còn lại phiên bản 8.

    Lưu ý rằng vì các phiên bản chính của TensorFlow thường được xuất bản cách nhau hơn 6 tháng, nên các đảm bảo cho các SavedModels được hỗ trợ nêu chi tiết ở trên mạnh hơn nhiều so với bảo đảm 6 tháng cho GraphDefs.

Cuối cùng, khi hỗ trợ cho một GraphDef phiên bản được giảm, chúng tôi sẽ cố gắng cung cấp các công cụ để tự động chuyển đổi đồ thị để hỗ trợ một phiên bản mới hơn GraphDef phiên bản.

Tính tương thích của đồ thị và điểm kiểm tra khi mở rộng TensorFlow

Phần này liên quan chỉ khi thực hiện những thay đổi không tương thích với GraphDef định dạng, chẳng hạn như khi thêm ops, loại bỏ ops, hoặc thay đổi các chức năng của ops hiện có. Phần trước sẽ đủ cho hầu hết người dùng.

Khả năng tương thích ngược và chuyển tiếp một phần

Chương trình lập phiên bản của chúng tôi có ba yêu cầu:

  • Khả năng tương thích ngược với các đồ thị tải hỗ trợ và các điểm kiểm tra được tạo ra với phiên bản cũ của TensorFlow.
  • Chuyển khả năng tương thích với các kịch bản hỗ trợ nơi nhà sản xuất của một đồ thị hoặc trạm kiểm soát được nâng cấp lên một phiên bản mới hơn của TensorFlow trước người tiêu dùng.
  • Bật TensorFlow phát triển theo những cách không tương thích. Ví dụ: xóa hoạt động, thêm thuộc tính và xóa thuộc tính.

Lưu ý rằng trong khi GraphDef phiên bản cơ chế tách biệt với phiên bản TensorFlow, những thay đổi ngược không tương thích với GraphDef định dạng vẫn còn bị hạn chế bởi Semantic Versioning. Chức năng phương tiện này chỉ có thể xóa hoặc thay đổi giữa MAJOR phiên bản của TensorFlow (như 1.7 để 2.0 ). Thêm vào đó, khả năng tương thích mong được thi hành trong phiên bản Patch ( 1.x.1 để 1.x.2 ví dụ).

Để đạt được khả năng tương thích ngược và chuyển tiếp và biết khi nào cần thực thi các thay đổi trong định dạng, biểu đồ và điểm kiểm tra có siêu dữ liệu mô tả thời điểm chúng được tạo ra. Các phần dưới đây chi tiết thi hành TensorFlow và hướng dẫn cho phát triển GraphDef phiên bản.

Các lược đồ phiên bản dữ liệu độc lập

Có các phiên bản dữ liệu khác nhau cho đồ thị và điểm kiểm tra. Hai định dạng dữ liệu phát triển với tốc độ khác nhau và cũng với tốc độ khác nhau so với TensorFlow. Cả hai hệ thống versioning được định nghĩa trong core/public/version.h . Bất cứ khi nào một phiên bản mới được thêm vào, một ghi chú sẽ được thêm vào tiêu đề nêu chi tiết những gì đã thay đổi và ngày tháng.

Dữ liệu, nhà sản xuất và người tiêu dùng

Chúng tôi phân biệt giữa các loại thông tin phiên bản dữ liệu sau:

  • nhà sản xuất: mã nhị phân mà tạo ra dữ liệu. Các nhà sản xuất có một phiên bản ( producer ) và một phiên bản tiêu dùng tối thiểu mà chúng phù hợp với ( min_consumer ).
  • người tiêu dùng: mã nhị phân có thể tiêu thụ dữ liệu. Người tiêu dùng có một phiên bản ( consumer ) và một phiên bản sản xuất tối thiểu mà chúng phù hợp với ( min_producer ).

Mỗi phần dữ liệu phiên bản có một VersionDef versions lĩnh vực trong đó ghi rõ producer đã làm cho các dữ liệu, min_consumer rằng nó là tương thích với, và một danh sách các bad_consumers phiên bản mà không được phép.

Theo mặc định, khi một nhà sản xuất làm cho một số dữ liệu, dữ liệu kế thừa của nhà sản xuất producermin_consumer phiên bản. bad_consumers có thể được thiết lập nếu các phiên bản tiêu dùng cụ thể được biết đến có chứa lỗi và phải được tránh. Người tiêu dùng có thể chấp nhận một phần dữ liệu nếu tất cả những điều sau đây đều đúng:

  • consumer > = dữ liệu của min_consumer
  • dữ liệu của producer > = tiêu dùng của min_producer
  • consumer không trong dữ liệu của bad_consumers

Kể từ khi cả hai nhà sản xuất và người tiêu dùng đến từ các cơ sở mã TensorFlow cùng, core/public/version.h chứa một phiên bản dữ liệu chính được coi là một trong hai producer hoặc consumer phụ thuộc vào bối cảnh và cả min_consumermin_producer (cần thiết cho các nhà sản xuất và người tiêu dùng, tương ứng) . Đặc biệt,

  • Đối với GraphDef phiên bản, chúng ta có TF_GRAPH_DEF_VERSION , TF_GRAPH_DEF_VERSION_MIN_CONSUMER , và TF_GRAPH_DEF_VERSION_MIN_PRODUCER .
  • Đối với phiên bản trạm kiểm soát, chúng tôi có TF_CHECKPOINT_VERSION , TF_CHECKPOINT_VERSION_MIN_CONSUMER , và TF_CHECKPOINT_VERSION_MIN_PRODUCER .

Thêm thuộc tính mới với thuộc tính mặc định vào tùy chọn hiện có

Thực hiện theo hướng dẫn bên dưới chỉ cung cấp cho bạn khả năng tương thích chuyển tiếp nếu tập hợp các hoạt động không thay đổi:

  1. Nếu tính tương thích là mong muốn, thiết lập strip_default_attrs để True trong khi xuất khẩu các mô hình sử dụng một trong hai tf.saved_model.SavedModelBuilder.add_meta_graph_and_variablestf.saved_model.SavedModelBuilder.add_meta_graph phương pháp của SavedModelBuilder lớp, hoặc tf.estimator.Estimator.export_saved_model
  2. Điều này loại bỏ các thuộc tính có giá trị mặc định tại thời điểm sản xuất / xuất mô hình. Điều này đảm bảo rằng xuất khẩu tf.MetaGraphDef không chứa op-thuộc tính mới khi giá trị mặc định được sử dụng.
  3. Việc có quyền kiểm soát này có thể cho phép người tiêu dùng lỗi thời (ví dụ: phân phối các tệp nhị phân chậm hơn so với các tệp nhị phân đào tạo) tiếp tục tải các mô hình và ngăn chặn sự gián đoạn trong việc phân phối mô hình.

Các phiên bản GraphDef đang phát triển

Phần này giải thích làm thế nào để sử dụng cơ chế versioning này để làm cho các loại khác nhau của thay đổi đối với GraphDef định dạng.

Thêm một op

Thêm op mới cho cả người tiêu dùng và nhà sản xuất cùng một lúc, và không thay đổi bất kỳ GraphDef phiên bản. Loại thay đổi này tự động tương thích ngược và không ảnh hưởng đến kế hoạch tương thích về phía trước vì các tập lệnh nhà sản xuất hiện có sẽ không đột nhiên sử dụng chức năng mới.

Thêm op và chuyển đổi các trình bao bọc Python hiện có để sử dụng nó

  1. Thực hiện chức năng tiêu dùng mới và tăng các GraphDef phiên bản.
  2. Nếu có thể làm cho các trình bao bọc chỉ sử dụng chức năng mới trong các trường hợp không hoạt động trước đây, thì các trình bao bọc có thể được cập nhật ngay bây giờ.
  3. Thay đổi trình bao bọc Python để sử dụng chức năng mới. Đừng increment min_consumer , kể từ khi mô hình không sử dụng op này không nên phá vỡ.

Xóa hoặc hạn chế chức năng của một op

  1. Sửa tất cả các tập lệnh của nhà sản xuất (không phải chính TensorFlow) để không sử dụng chức năng hoặc chức năng bị cấm.
  2. Thặng dư GraphDef phiên bản và thực hiện các chức năng của người tiêu dùng mới có lệnh cấm các op loại bỏ hoặc chức năng cho GraphDefs tại phiên bản mới trở lên. Nếu có thể, hãy TensorFlow sản xuất dừng GraphDefs với các chức năng cấm. Để làm như vậy, thêm REGISTER_OP(...).Deprecated(deprecated_at_version, message) .
  3. Chờ bản phát hành chính cho các mục đích tương thích ngược.
  4. Tăng min_producer lên phiên bản GraphDef từ (2) và loại bỏ các chức năng hoàn toàn.

Thay đổi chức năng của một op

  1. Thêm một op tương tự mới có tên SomethingV2 hoặc tương đương và trải qua quá trình thêm nó và chuyển wrappers Python hiện có để sử dụng nó. Để đảm bảo khả năng tương thích về phía trước sử dụng kiểm tra đề xuất trong compat.py khi thay đổi giấy gói Python.
  2. Loại bỏ op cũ (Chỉ có thể diễn ra với sự thay đổi phiên bản lớn do khả năng tương thích ngược).
  3. Tăng min_consumer để loại trừ người tiêu dùng với các op cũ, thêm lưng op cũ như một bí danh cho SomethingV2 , và trải qua quá trình chuyển đổi giấy gói Python hiện có để sử dụng nó.
  4. Đi qua quá trình này để loại bỏ SomethingV2 .

Cấm một phiên bản dành cho người tiêu dùng không an toàn

  1. Bump GraphDef phiên bản và thêm phiên bản xấu để bad_consumers cho tất cả GraphDefs mới. Nếu có thể, thêm vào bad_consumers chỉ cho GraphDefs có chứa một op nhất định hoặc tương đương.
  2. Nếu người tiêu dùng hiện tại có phiên bản xấu, hãy đẩy họ ra càng sớm càng tốt.