Lõi liên kết

Tài liệu này giới thiệu lớp cốt lõi của TFF đóng vai trò là nền tảng cho Học liên kết và các thuật toán liên kết không học tập có thể có trong tương lai.

Để có phần giới thiệu ngắn gọn về Federated Core, vui lòng đọc các hướng dẫn sau, vì chúng giới thiệu một số khái niệm cơ bản bằng ví dụ và trình bày từng bước cách xây dựng thuật toán tính trung bình liên kết đơn giản.

Chúng tôi cũng khuyến khích bạn làm quen với Học tập liên kết và các hướng dẫn liên quan về phân loại hình ảnhtạo văn bản , vì việc sử dụng API lõi liên kết (API FC) cho học tập liên kết cung cấp bối cảnh quan trọng cho một số lựa chọn mà chúng tôi đã thực hiện trong thiết kế lớp này.

Tổng quan

Mục tiêu, mục đích sử dụng và phạm vi

Federated Core (FC) được hiểu rõ nhất là môi trường lập trình để triển khai các tính toán phân tán, tức là các tính toán liên quan đến nhiều máy tính (điện thoại di động, máy tính bảng, thiết bị nhúng, máy tính để bàn, cảm biến, máy chủ cơ sở dữ liệu, v.v.) mà mỗi máy có thể thực hiện không- xử lý đơn giản cục bộ và liên lạc qua mạng để điều phối công việc của họ.

Thuật ngữ phân tán rất chung chung và TFF không nhắm mục tiêu tất cả các loại thuật toán phân tán có thể có, vì vậy chúng tôi thích sử dụng thuật ngữ tính toán liên kết ít chung chung hơn để mô tả các loại thuật toán có thể được biểu thị trong khung này.

Mặc dù việc xác định thuật ngữ tính toán liên kết theo cách hoàn toàn chính thức nằm ngoài phạm vi của tài liệu này, hãy nghĩ đến các loại thuật toán mà bạn có thể thấy được thể hiện bằng mã giả trong một ấn phẩm nghiên cứu mô tả thuật toán học phân tán mới.

Tóm lại, mục tiêu của FC là cho phép biểu diễn nhỏ gọn tương tự, ở mức độ trừu tượng giống như mã giả tương tự, của logic chương trình không phải là mã giả mà đúng hơn là có thể thực thi được trong nhiều môi trường đích khác nhau.

Đặc điểm xác định chính của các loại thuật toán mà FC được thiết kế để thể hiện là hành động của những người tham gia hệ thống được mô tả theo cách tập thể. Vì vậy, chúng ta có xu hướng nói về từng thiết bị chuyển đổi dữ liệu cục bộ và các thiết bị điều phối công việc của một điều phối viên tập trung phát sóng , thu thập hoặc tổng hợp kết quả của chúng.

Trong khi TFF được thiết kế để có thể vượt xa các kiến ​​trúc máy khách-máy chủ đơn giản, khái niệm xử lý tập thể là cơ bản. Điều này là do nguồn gốc của TFF trong học tập liên kết, một công nghệ ban đầu được thiết kế để hỗ trợ tính toán trên dữ liệu có khả năng nhạy cảm vẫn nằm dưới sự kiểm soát của thiết bị khách và dữ liệu đó có thể không được tải xuống một vị trí tập trung vì lý do bảo mật. Mặc dù mỗi khách hàng trong các hệ thống như vậy đóng góp dữ liệu và khả năng xử lý để hệ thống tính toán kết quả (kết quả mà chúng tôi thường mong đợi là có giá trị đối với tất cả những người tham gia), chúng tôi cũng cố gắng bảo vệ quyền riêng tư và ẩn danh của mỗi khách hàng.

Do đó, trong khi hầu hết các khung cho điện toán phân tán được thiết kế để thể hiện việc xử lý từ quan điểm của từng người tham gia - nghĩa là ở cấp độ trao đổi tin nhắn điểm-điểm riêng lẻ và sự phụ thuộc lẫn nhau của quá trình chuyển đổi trạng thái cục bộ của người tham gia với các tin nhắn đến và đi. , Lõi liên kết của TFF được thiết kế để mô tả hành vi của hệ thống từ góc độ toàn hệ thống toàn cầu (tương tự như MapReduce ).

Do đó, trong khi các khung phân phối cho các mục đích chung có thể cung cấp các hoạt động như gửinhận dưới dạng các khối xây dựng, FC cung cấp các khối xây dựng như tff.federated_sum , tff.federated_reduce hoặc tff.federated_broadcast đóng gói các giao thức phân tán đơn giản.

Ngôn ngữ

Giao diện Python

TFF sử dụng ngôn ngữ nội bộ để biểu diễn các phép tính liên kết, cú pháp của ngôn ngữ này được xác định bằng cách biểu diễn có thể tuần tự hóa trong Computing.proto . Tuy nhiên, người dùng FC API thường không cần phải tương tác trực tiếp với ngôn ngữ này. Thay vào đó, chúng tôi cung cấp API Python (không gian tên tff ) bao quanh nó như một cách để xác định các phép tính.

Cụ thể, TFF cung cấp các trình trang trí hàm Python chẳng hạn như tff.federated_computation để theo dõi phần thân của các hàm được trang trí và tạo ra các biểu diễn tuần tự của logic tính toán liên kết bằng ngôn ngữ của TFF. Một hàm được trang trí bằng tff.federated_computation đóng vai trò là vật mang biểu diễn được tuần tự hóa như vậy và có thể nhúng nó như một khối xây dựng trong phần nội dung của một phép tính khác hoặc thực thi nó theo yêu cầu khi được gọi.

Đây chỉ là một ví dụ; bạn có thể tìm thấy nhiều ví dụ hơn trong hướng dẫn về thuật toán tùy chỉnh .

@tff.federated_computation(tff.FederatedType(np.float32, tff.CLIENTS))
def get_average_temperature(sensor_readings):
  return tff.federated_mean(sensor_readings)

Những độc giả quen thuộc với TensorFlow không háo hức sẽ thấy cách tiếp cận này tương tự như việc viết mã Python sử dụng các hàm như tf.add hoặc tf.reduce_sum trong một phần mã Python xác định biểu đồ TensorFlow. Mặc dù mã được thể hiện về mặt kỹ thuật bằng Python, mục đích của nó là xây dựng một biểu diễn tuần tự hóa của tf.Graph bên dưới và chính biểu đồ chứ không phải mã Python được thực thi nội bộ bởi thời gian chạy TensorFlow. Tương tự như vậy, người ta có thể coi tff.federated_mean như việc chèn một op liên kết vào một phép tính liên kết được biểu thị bằng get_average_temperature .

Một phần lý do khiến FC xác định ngôn ngữ có liên quan đến thực tế là, như đã lưu ý ở trên, các tính toán liên kết chỉ định các hành vi tập thể phân tán và do đó, logic của chúng không cục bộ. Ví dụ, TFF cung cấp cho người vận hành các đầu vào và đầu ra có thể tồn tại ở những nơi khác nhau trong mạng.

Điều này đòi hỏi một ngôn ngữ và một hệ thống kiểu có thể nắm bắt được khái niệm về tính phân tán.

Loại hệ thống

Federated Core cung cấp các loại loại sau. Khi mô tả các kiểu này, chúng tôi đề cập đến các hàm tạo kiểu cũng như giới thiệu một ký hiệu nhỏ gọn, vì đây là một cách thuận tiện hoặc mô tả các kiểu tính toán và toán tử.

Đầu tiên, đây là các loại loại có khái niệm tương tự như các loại được tìm thấy trong các ngôn ngữ chính thống hiện có:

  • Các loại tenxơ ( tff.TensorType ). Giống như trong TensorFlow, chúng có dtypeshape . Sự khác biệt duy nhất là các đối tượng thuộc loại này không bị giới hạn ở các phiên bản tf.Tensor trong Python đại diện cho kết quả đầu ra của các hoạt động TensorFlow trong biểu đồ TensorFlow, nhưng cũng có thể bao gồm các đơn vị dữ liệu có thể được tạo ra, ví dụ: dưới dạng đầu ra của một hệ thống phân tán. giao thức tổng hợp. Do đó, loại tensor TFF chỉ đơn giản là một phiên bản trừu tượng của một biểu diễn vật lý cụ thể của loại đó trong Python hoặc TensorFlow.

    TensorTypes của TFF có thể xử lý hình dạng (tĩnh) chặt chẽ hơn so với TensorFlow. Ví dụ: hệ thống kiểu của TFF xử lý một tensor có hạng không xác định là có thể gán được từ bất kỳ tensor nào khác có cùng dtype , nhưng không thể gán cho bất kỳ tensor nào có hạng cố định. Cách xử lý này ngăn ngừa một số lỗi thời gian chạy nhất định (ví dụ: cố gắng định hình lại một tensor có thứ hạng không xác định thành một hình có số phần tử không chính xác), với cái giá phải trả là tính toán mà TFF chấp nhận là hợp lệ sẽ nghiêm ngặt hơn.

    Ký hiệu thu gọn cho các loại tensor là dtype hoặc dtype[shape] . Ví dụ: int32int32[10] lần lượt là các loại số nguyên và vectơ int.

  • Các loại trình tự ( tff.SequenceType ). Đây là những khái niệm trừu tượng tương đương của TFF với khái niệm cụ thể của TensorFlow về tf.data.Dataset s. Các phần tử của chuỗi có thể được sử dụng một cách tuần tự và có thể bao gồm các kiểu phức tạp.

    Biểu diễn thu gọn của các loại chuỗi là T* , trong đó T là loại phần tử. Ví dụ int32* đại diện cho một chuỗi số nguyên.

  • Các loại tuple được đặt tên ( tff.StructType ). Đây là cách TFF xây dựng các bộ dữ liệu và cấu trúc giống như từ điển có số phần tử được xác định trước với các kiểu cụ thể, được đặt tên hoặc không được đặt tên. Điều quan trọng là, khái niệm bộ dữ liệu được đặt tên của TFF bao gồm sự tương đương trừu tượng của các bộ dữ liệu đối số của Python, tức là các tập hợp các phần tử trong đó một số, nhưng không phải tất cả đều được đặt tên và một số có vị trí.

    Ký hiệu thu gọn cho các bộ dữ liệu được đặt tên là <n_1=T_1, ..., n_k=T_k> , trong đó n_k là tên phần tử tùy chọn và T_k là loại phần tử. Ví dụ: <int32,int32> là ký hiệu thu gọn cho một cặp số nguyên không tên và <X=float32,Y=float32> là ký hiệu thu gọn cho một cặp số float có tên XY có thể biểu thị một điểm trên mặt phẳng . Các bộ dữ liệu có thể được lồng vào nhau cũng như trộn lẫn với các loại khác, ví dụ: <X=float32,Y=float32>* sẽ là một ký hiệu thu gọn cho một chuỗi các điểm.

  • Các loại hàm ( tff.FunctionType ). TFF là một khung lập trình chức năng, với các hàm được coi là giá trị hạng nhất . Hàm có nhiều nhất một đối số và có chính xác một kết quả.

    Ký hiệu thu gọn cho các hàm là (T -> U) , trong đó T là loại đối số và U là loại kết quả hoặc ( -> U) nếu không có đối số (mặc dù các hàm không có đối số là suy biến khái niệm tồn tại chủ yếu ở cấp độ Python). Ví dụ (int32* -> int32) là ký hiệu cho một loại hàm rút gọn một chuỗi số nguyên thành một giá trị số nguyên duy nhất.

Các loại sau đây đề cập đến khía cạnh hệ thống phân tán của tính toán TFF. Vì các khái niệm này hơi khác với TFF nên chúng tôi khuyến khích bạn tham khảo hướng dẫn về thuật toán tùy chỉnh để có thêm bình luận và ví dụ.

  • Loại vị trí . Loại này chưa được hiển thị trong API công khai ngoài dạng 2 chữ tff.SERVERtff.CLIENTS mà bạn có thể coi là hằng số của loại này. Tuy nhiên, nó được sử dụng nội bộ và sẽ được giới thiệu trong API công khai trong các bản phát hành trong tương lai. Biểu diễn nhỏ gọn của loại này là placement .

    Vị trí đại diện cho một tập thể những người tham gia hệ thống đóng một vai trò cụ thể. Bản phát hành đầu tiên nhắm mục tiêu tính toán máy khách-máy chủ, trong đó có 2 nhóm người tham gia: máy kháchmáy chủ (bạn có thể coi nhóm sau là một nhóm đơn lẻ). Tuy nhiên, trong các kiến ​​trúc phức tạp hơn, có thể có các vai trò khác, chẳng hạn như người tổng hợp trung gian trong hệ thống nhiều tầng, người có thể thực hiện các kiểu tổng hợp khác nhau hoặc sử dụng các kiểu nén/giải nén dữ liệu khác với các kiểu được máy chủ hoặc máy chủ sử dụng. các khách hàng.

    Mục đích chính của việc xác định khái niệm vị trí là làm cơ sở cho việc xác định các loại liên kết .

  • Các loại liên kết ( tff.FederatedType ). Giá trị của loại liên kết là giá trị được lưu trữ bởi một nhóm người tham gia hệ thống được xác định bởi một vị trí cụ thể (chẳng hạn như tff.SERVER hoặc tff.CLIENTS ). Loại liên kết được xác định bởi giá trị vị trí (do đó, nó là loại phụ thuộc ), loại thành phần thành viên (loại nội dung mà mỗi người tham gia lưu trữ cục bộ) và bit bổ sung all_equal xác định xem tất cả người tham gia có ở địa phương hay không lưu trữ cùng một mặt hàng.

    Ký hiệu nhỏ gọn cho loại giá trị được liên kết bao gồm các mục (thành phần thành viên) thuộc loại T , mỗi mục được lưu trữ theo nhóm (vị trí) G lần lượt là T@G hoặc {T}@G với bit all_equal được đặt hoặc không được đặt.

    Ví dụ:

    • {int32}@CLIENTS đại diện cho một giá trị liên kết bao gồm một tập hợp các số nguyên có khả năng phân biệt, mỗi số nguyên cho mỗi thiết bị khách. Lưu ý rằng chúng ta đang nói về một giá trị liên kết duy nhất bao gồm nhiều mục dữ liệu xuất hiện ở nhiều vị trí trên mạng. Một cách để nghĩ về nó là một loại tenxơ có chiều "mạng", mặc dù sự tương tự này không hoàn hảo vì TFF không cho phép truy cập ngẫu nhiên vào các thành phần thành viên của một giá trị liên kết.

    • {<X=float32,Y=float32>*}@CLIENTS đại diện cho một tập dữ liệu liên kết , một giá trị bao gồm nhiều chuỗi tọa độ XY , một chuỗi cho mỗi thiết bị khách.

    • <weights=float32[10,5],bias=float32[5]>@SERVER đại diện cho một bộ giá trị có tên gồm các tensor trọng số và độ lệch tại máy chủ. Vì chúng ta đã bỏ dấu ngoặc nhọn nên điều này cho biết bit all_equal đã được đặt, tức là chỉ có một bộ dữ liệu duy nhất (bất kể có thể có bao nhiêu bản sao máy chủ trong một cụm lưu trữ giá trị này).

Khối xây dựng

Ngôn ngữ của Federated Core là một dạng phép tính lambda , với một vài thành phần bổ sung.

Nó cung cấp các tóm tắt lập trình sau hiện được hiển thị trong API công khai:

  • Tính toán TensorFlow ( tff.tensorflow.computation ). Đây là các phần của mã TensorFlow được bao bọc dưới dạng các thành phần có thể tái sử dụng trong TFF bằng cách sử dụng trình trang trí tff.tensorflow.computation . Chúng luôn có các loại chức năng và không giống như các hàm trong TensorFlow, chúng có thể lấy các tham số có cấu trúc hoặc trả về kết quả có cấu trúc của một loại trình tự.

    Dưới đây là một ví dụ, tính toán TF thuộc loại (int32* -> int) sử dụng toán tử tf.data.Dataset.reduce để tính tổng các số nguyên:

    @tff.tensorflow.computation(tff.SequenceType(np.int32))
    def add_up_integers(x):
      return x.reduce(np.int32(0), lambda x, y: x + y)
    
  • Toán tử nội tại hoặc liên kết ( tff.federated_... ). Đây là thư viện các hàm như tff.federated_sum hoặc tff.federated_broadcast tạo nên phần lớn FC API, hầu hết chúng đại diện cho các toán tử truyền thông phân tán để sử dụng với TFF.

    Chúng tôi gọi chúng là các hàm nội tại bởi vì, hơi giống các hàm nội tại , chúng là một tập hợp các toán tử có kết thúc mở, có thể mở rộng được TFF hiểu và được biên dịch thành mã cấp thấp hơn.

    Hầu hết các toán tử này đều có các tham số và kết quả thuộc loại liên kết và hầu hết đều là các mẫu có thể áp dụng cho nhiều loại dữ liệu khác nhau.

    Ví dụ: tff.federated_broadcast có thể được coi là toán tử mẫu của loại chức năng T@SERVER -> T@CLIENTS .

  • Biểu thức Lambda ( tff.federated_computation ). Biểu thức lambda trong TFF tương đương với lambda hoặc def trong Python; nó bao gồm tên tham số và phần nội dung (biểu thức) chứa các tham chiếu đến tham số này.

    Trong mã Python, những thứ này có thể được tạo bằng cách trang trí các hàm Python bằng tff.federated_computation và xác định một đối số.

    Đây là ví dụ về biểu thức lambda mà chúng tôi đã đề cập trước đó:

    @tff.federated_computation(tff.FederatedType(np.float32, tff.CLIENTS))
    def get_average_temperature(sensor_readings):
      return tff.federated_mean(sensor_readings)
    
  • Vị trí chữ . Hiện tại, chỉ có tff.SERVERtff.CLIENTS cho phép xác định các tính toán máy khách-máy chủ đơn giản.

  • Lời gọi hàm ( __call__ ). Bất kỳ thứ gì có loại chức năng đều có thể được gọi bằng cú pháp __call__ tiêu chuẩn của Python. Lệnh gọi là một biểu thức, loại của biểu thức này giống với loại kết quả của hàm được gọi.

    Ví dụ:

    • add_up_integers(x) thể hiện lệnh gọi tính toán TensorFlow được xác định trước đó trên đối số x . Loại biểu thức này là int32 .

    • tff.federated_mean(sensor_readings) thể hiện lệnh gọi toán tử tính trung bình liên kết trên sensor_readings . Loại biểu thức này là float32@SERVER (giả sử ngữ cảnh từ ví dụ trên).

  • Hình thành các bộ dữ liệuchọn các phần tử của chúng. Các biểu thức Python có dạng [x, y] , x[y] hoặc xy xuất hiện trong phần thân của các hàm được trang trí bằng tff.federated_computation .