Transformers documentation

RWKV

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Mô hình này đã được đóng góp cho Hugging Face Transformers vào ngày 2023-05-09.

RWKV

Tổng quan

Mô hình RWKV (phiên bản 4) được đề xuất trong repo này

Đề xuất một điều chỉnh trong cơ chế chú ý Transformer truyền thống để biến nó thành tuyến tính. Nhờ đó, mô hình có thể được sử dụng như một mạng nơ-ron tuần tự: việc truyền các đầu vào cho mốc thời gian 0 và mốc thời gian 1 cùng lúc là tương đương với việc truyền đầu vào tại mốc thời gian 0, sau đó truyền đầu vào tại mốc thời gian 1 cùng với trạng thái tại mốc thời gian 0 (xem ví dụ bên dưới).

Điều này có thể hiệu quả hơn so với Transformer thông thường và có thể xử lý câu có độ dài bất kỳ (ngay cả khi mô hình sử dụng độ dài ngữ cảnh cố định cho huấn luyện).

Mô hình này được đóng góp bởi sgugger. Mã nguồn gốc có thể được tìm thấy tại đây.

Ví dụ sử dụng

import torch

from transformers import AutoTokenizer, RwkvModel


model = RwkvModel.from_pretrained("sgugger/rwkv-430M-pile", device_map="auto")
tokenizer = AutoTokenizer.from_pretrained("sgugger/rwkv-430M-pile")

inputs = tokenizer("This is an example.", return_tensors="pt").to(model.device)
# Feed everything to the model
outputs = model(inputs["input_ids"])
output_whole = outputs.last_hidden_state

outputs = model(inputs["input_ids"][:, :2])
output_one = outputs.last_hidden_state

# Using the state computed on the first inputs, we will get the same output
outputs = model(inputs["input_ids"][:, 2:], state=outputs.state)
output_two = outputs.last_hidden_state

torch.allclose(torch.cat([output_one, output_two], dim=1), output_whole, atol=1e-5)

Nếu bạn muốn đảm bảo mô hình dừng tạo khi phát hiện '\n\n', chúng tôi khuyên bạn nên sử dụng các tiêu chí dừng sau:

from transformers import StoppingCriteria


class RwkvStoppingCriteria(StoppingCriteria):
    def __init__(self, eos_sequence = [187,187], eos_token_id = 537):
        self.eos_sequence = eos_sequence
        self.eos_token_id = eos_token_id

    def __call__(self, input_ids: torch.LongTensor, scores: torch.Tensor, **kwargs) -> bool:
        last_2_ids = input_ids[:,-2:].tolist()
        return self.eos_sequence in last_2_ids


output = model.generate(inputs["input_ids"], max_new_tokens=64, stopping_criteria = [RwkvStoppingCriteria()])

Ghi chú

  • Sử dụng left padding cho việc tạo batched. Xem Padding side.

RwkvConfig

lớp transformers.RwkvConfig

< >

( transformers_version: str | None = Nonearchitectures: list[str] | None = Noneoutput_hidden_states: bool | None = Falsereturn_dict: bool | None = Truedtype: str | torch.dtype | None = Nonechunk_size_feed_forward: int = 0is_encoder_decoder: bool = Falseid2label: dict[int, str] | dict[str, str] | None = Nonelabel2id: dict[str, int] | dict[str, str] | None = Noneproblem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = Nonevocab_size: int = 50277context_length: int = 1024hidden_size: int = 4096num_hidden_layers: int = 32attention_hidden_size: int | None = Noneintermediate_size: int | None = Nonelayer_norm_epsilon: float = 1e-05bos_token_id: int | None = 0eos_token_id: int | list[int] | None = 0rescale_every: int = 6tie_word_embeddings: bool = Falseuse_cache: bool = True )

Tham số

  • vocab_size (int, tùy chọn, mặc định là 50277) — Kích thước từ vựng của mô hình. Xác định số lượng token khác nhau có thể được biểu diễn bởi input_ids.
  • context_length (int, tùy chọn, mặc định là 1024) — Chiều dài chuỗi tối đa mà mô hình này có thể được sử dụng trong một lần forward (việc sử dụng nó ở chế độ RNN cho phép dùng bất kỳ chiều dài chuỗi nào).
  • hidden_size (int, tùy chọn, mặc định là 4096) — Kích thước của các biểu diễn ẩn.
  • num_hidden_layers (int, tùy chọn, mặc định là 32) — Số lượng lớp ẩn trong bộ giải mã Transformer.
  • attention_hidden_size (int, tùy chọn) — Kích thước chiều của các trạng thái ẩn attention. Mặc định sẽ là hidden_size nếu không được đặt.
  • intermediate_size (int, tùy chọn) — Kích thước của các biểu diễn MLP.
  • layer_norm_epsilon (float, tùy chọn, mặc định là 1e-05) — Giá trị epsilon được sử dụng bởi các lớp chuẩn hóa lớp (layer normalization).
  • bos_token_id (int, tùy chọn, mặc định là 0) — Token id được sử dụng cho đầu luồng trong bảng từ vựng.
  • eos_token_id (Union[int, list[int]], tùy chọn, mặc định là 0) — Token id được sử dụng cho end-of-stream trong bảng từ vựng.
  • rescale_every (int, tùy chọn, mặc định là 6) — Khi suy luận, các trạng thái ẩn (và trọng số của các lớp đầu ra tương ứng) sẽ được chia cho 2 mỗi rescale_every lớp. Nếu đặt thành 0 hoặc một số âm, sẽ không thực hiện việc chia lại.
  • tie_word_embeddings (bool, tùy chọn, mặc định là False) — Có nên gắn kết các trọng số nhúng theo ánh xạ tied_weights_keys của mô hình hay không.
  • use_cache (bool, tùy chọn, mặc định là True) — Xác định xem mô hình có nên trả về các chú ý key/values cuối cùng hay không (không được sử dụng bởi tất cả các mô hình). Chỉ liên quan nếu config.is_decoder=True hoặc khi mô hình là mô hình sinh chỉ có decoder.

Đây là lớp cấu hình để lưu trữ cấu hình của một RwkvModel. Nó được sử dụng để khởi tạo một mô hình Rwkv theo các đối số được chỉ định, xác định kiến trúc của mô hình. Khởi tạo một cấu hình với các giá trị mặc định sẽ tạo ra một cấu hình tương tự như cấu hình của RWKV/rwkv-4-169m-pile

Các đối tượng cấu hình kế thừa từ PreTrainedConfig và có thể được sử dụng để kiểm soát đầu ra của mô hình. Đọc tài liệu từ PreTrainedConfig để biết thêm thông tin.

Ví dụ:

>>> from transformers import RwkvConfig, RwkvModel

>>> # Initializing a Rwkv configuration
>>> configuration = RwkvConfig()

>>> # Initializing a model (with random weights) from the configuration
>>> model = RwkvModel(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config

RwkvModel

lớp transformers.RwkvModel

< >

( config: RwkvConfig )

Tham số

  • config (RwkvConfig) — Lớp cấu hình mô hình chứa tất cả các tham số của mô hình. Khởi tạo bằng tệp cấu hình không tải trọng số liên quan đến mô hình, chỉ tải cấu hình. Xem phương thức from_pretrained() để tải trọng số của mô hình.

Mô hình Rwkv cơ bản, xuất ra các trạng thái ẩn thô mà không có bất kỳ đầu (head) cụ thể nào ở phía trên.

Mô hình này kế thừa từ PreTrainedModel. Xem tài liệu của lớp cha để biết các phương thức chung mà thư viện triển khai cho tất cả các mô hình của nó (chẳng hạn như tải xuống hoặc lưu trữ, thay đổi kích thước các nhúng đầu vào, cắt tỉa các đầu, v.v.)

Mô hình này cũng là một lớp con của torch.nn.Module trong PyTorch. Hãy sử dụng nó như một Module PyTorch thông thường và tham khảo tài liệu PyTorch cho mọi vấn đề liên quan đến cách sử dụng và hành vi chung.

forward

< >

( input_ids: typing.Optional[torch.LongTensor] = Noneattention_mask: typing.Optional[torch.LongTensor] = Noneinputs_embeds: typing.Optional[torch.Tensor] = Nonestate: list[torch.Tensor] | None = Noneuse_cache: bool | None = Noneoutput_attentions: bool | None = Noneoutput_hidden_states: bool | None = Nonereturn_dict: bool | None = None**kwargs ) → RwkvOutput or tuple(torch.Tensor)

Tham số

  • input_ids (torch.LongTensor có dạng (batch_size, input_ids_length)) — input_ids_length = sequence_length nếu past_key_values là None nếu không past_key_values.get_seq_length() (sequence_length của các trạng thái past key value đầu vào). Chỉ số của các token trong chuỗi đầu vào theo từ điển.

    Nếu past_key_values được sử dụng, chỉ những input_ids chưa được tính toán phần quá khứ nên được truyền vào dưới dạng input_ids.

    Các chỉ số có thể được lấy bằng cách sử dụng AutoTokenizer. Xem PreTrainedTokenizer.encode() và PreTrainedTokenizer.call() để biết thêm chi tiết.

    ID đầu vào là gì?

  • attention_mask (torch.LongTensor có hình dạng (batch_size, sequence_length), tùy chọn) — Mặt nạ để tránh thực hiện attention trên các chỉ số token padding. Các giá trị mặt nạ được chọn trong [0, 1]:
    • 1 cho các token không bị che,
    • 0 cho các token bị che.

    Mặt nạ chú ý là gì?

  • inputs_embeds (torch.Tensor có hình dạng (batch_size, sequence_length, hidden_size), tùy chọn) — Tùy chọn, thay vì truyền input_ids, bạn có thể chọn truyền trực tiếp một biểu diễn nhúng. Điều này hữu ích nếu bạn muốn kiểm soát nhiều hơn cách chuyển đổi các chỉ số input_ids thành các vector liên quan so với ma trận tra cứu nhúng nội bộ của mô hình.
  • state (tuple gồm năm torch.Tensor có shape (batch_size, hidden_size, num_hidden_layers), optional) — Nếu được truyền vào, mô hình sẽ sử dụng trạng thái trước đó trong tất cả các khối (điều này sẽ cho ra đầu ra cho input_ids được cung cấp như thể mô hình đã thêm state_input_ids + input_ids làm ngữ cảnh).
  • use_cache (bool, tùy chọn) — Nếu được đặt thành True, trạng thái cuối cùng sẽ được trả về và có thể được sử dụng để nhanh chóng tạo ra các logits tiếp theo.
  • output_attentions (bool, tùy chọn) — Có trả về các tensor attentions của tất cả các lớp attention hay không. Xem attentions trong phần tensor được trả về để biết thêm chi tiết.
  • output_hidden_states (bool, tùy chọn) — Có trả về trạng thái ẩn (hidden states) của tất cả các lớp hay không. Xem hidden_states trong phần tensor trả về để biết thêm chi tiết.
  • return_dict (bool, tùy chọn) — Có nên trả về một ModelOutput thay vì một tuple thông thường hay không.

Trả về

RwkvOutput hoặc tuple(torch.Tensor)

Một RwkvOutput hoặc một tuple của torch.Tensor (nếu return_dict=False được truyền hoặc khi config.return_dict=False) bao gồm các thành phần khác nhau tùy thuộc vào cấu hình (RwkvConfig) và đầu vào.

Phương thức forward của RwkvModel ghi đè lên phương thức đặc biệt __call__.

Mặc dù công thức cho bước truyền tiến cần được định nghĩa bên trong hàm này, người dùng nên gọi instance của Module sau đó thay vì gọi hàm này, vì instance Module sẽ đảm nhận việc thực hiện các bước tiền xử lý và hậu xử lý, trong khi hàm này sẽ lặng lẽ bỏ qua chúng.

  • last_hidden_state (torch.Tensor có hình dạng (batch_size, sequence_length, hidden_size), tùy chọn) — Chuỗi các trạng thái ẩn (hidden-states) tại đầu ra của lớp cuối cùng của mô hình.

  • state (list gồm năm torch.Tensor có hình dạng (batch_size, hidden_size, num_hidden_layers)) — Trạng thái của mô hình tại bước thời gian cuối cùng. Có thể được sử dụng trong phương thức forward với input_ids tiếp theo để tránh việc cung cấp lại input_ids cũ.

  • hidden_states (tuple[torch.Tensor, ...], tuỳ chọn, được trả về khi output_hidden_states=True được truyền vào hoặc khi config.output_hidden_states=True) — Tuple của torch.Tensor (một cho đầu ra của embeddings, nếu mô hình có lớp embedding, + một cho đầu ra của mỗi lớp) có hình dạng (batch_size, sequence_length, hidden_size).

    Trạng thái ẩn của mô hình tại đầu ra của mỗi lớp cùng với các đầu ra embedding ban đầu tùy chọn.

  • attentions (tuple[torch.Tensor, ...], tuỳ chọn, được trả về khi output_attentions=True được truyền vào hoặc khi config.output_attentions=True) — Tuple của torch.Tensor (một cho mỗi lớp) có hình dạng (batch_size, num_heads, sequence_length, sequence_length).

    Trọng số chú ý sau softmax của attention, được sử dụng để tính trung bình có trọng số trong các đầu self-attention.

RwkvLMHeadModel

lớp transformers.RwkvForCausalLM

< >

( config: RwkvConfig )

Tham số

  • config (RwkvConfig) — Lớp cấu hình mô hình chứa tất cả các tham số của mô hình. Khởi tạo bằng tệp cấu hình không tải trọng số liên quan đến mô hình, chỉ tải cấu hình. Xem phương thức from_pretrained() để tải trọng số của mô hình.

Biến đổi mô hình RWKV với đầu mô hình hóa ngôn ngữ phía trên (lớp tuyến tính với trọng số được liên kết với các nhúng đầu vào).

Mô hình này kế thừa từ PreTrainedModel. Xem tài liệu của lớp cha để biết các phương thức chung mà thư viện triển khai cho tất cả các mô hình của nó (chẳng hạn như tải xuống hoặc lưu trữ, thay đổi kích thước các nhúng đầu vào, cắt tỉa các đầu, v.v.)

Mô hình này cũng là một lớp con của torch.nn.Module trong PyTorch. Hãy sử dụng nó như một Module PyTorch thông thường và tham khảo tài liệu PyTorch cho mọi vấn đề liên quan đến cách sử dụng và hành vi chung.

forward

< >

( input_ids: typing.Optional[torch.LongTensor] = Noneattention_mask: typing.Optional[torch.LongTensor] = Noneinputs_embeds: typing.Optional[torch.Tensor] = Nonestate: list[torch.Tensor] | None = Nonelabels: typing.Optional[torch.LongTensor] = Noneuse_cache: bool | None = Noneoutput_attentions: bool | None = Noneoutput_hidden_states: bool | None = Nonereturn_dict: bool | None = Nonelogits_to_keep: typing.Union[int, torch.Tensor] = 0**kwargs ) → RwkvCausalLMOutput or tuple(torch.Tensor)

Tham số

  • input_ids (torch.LongTensor có dạng (batch_size, input_ids_length)) — input_ids_length = sequence_length nếu past_key_values là None nếu không past_key_values.get_seq_length() (sequence_length của các trạng thái past key value đầu vào). Chỉ số của các token trong chuỗi đầu vào theo từ điển.

    Nếu past_key_values được sử dụng, chỉ những input_ids chưa được tính toán phần quá khứ nên được truyền vào dưới dạng input_ids.

    Các chỉ số có thể được lấy bằng cách sử dụng AutoTokenizer. Xem PreTrainedTokenizer.encode() và PreTrainedTokenizer.call() để biết thêm chi tiết.

    ID đầu vào là gì?

  • attention_mask (torch.LongTensor có hình dạng (batch_size, sequence_length), tùy chọn) — Mặt nạ để tránh thực hiện attention trên các chỉ số token padding. Các giá trị mặt nạ được chọn trong [0, 1]:
    • 1 cho các token không bị che,
    • 0 cho các token bị che.

    Mặt nạ chú ý là gì?

  • inputs_embeds (torch.Tensor có hình dạng (batch_size, sequence_length, hidden_size), tùy chọn) — Tùy chọn, thay vì truyền input_ids, bạn có thể chọn truyền trực tiếp một biểu diễn nhúng. Điều này hữu ích nếu bạn muốn kiểm soát nhiều hơn cách chuyển đổi các chỉ số input_ids thành các vector liên quan so với ma trận tra cứu nhúng nội bộ của mô hình.
  • state (tuple gồm năm torch.Tensor có shape (batch_size, hidden_size, num_hidden_layers), optional) — Nếu được truyền vào, mô hình sẽ sử dụng trạng thái trước đó trong tất cả các khối (điều này sẽ cho ra đầu ra cho input_ids được cung cấp như thể mô hình đã thêm state_input_ids + input_ids làm ngữ cảnh).
  • labels (torch.LongTensor có shape (batch_size, sequence_length), tùy chọn) — Nhãn cho mô hình hóa ngôn ngữ. Lưu ý rằng các nhãn được dịch chuyển bên trong mô hình, tức là bạn có thể đặt labels = input_ids Các chỉ số được chọn trong [-100, 0, ..., config.vocab_size] Tất cả các nhãn được đặt thành -100 sẽ bị bỏ qua (che), loss chỉ được tính cho các nhãn trong [0, ..., config.vocab_size]
  • use_cache (bool, tùy chọn) — Nếu được đặt thành True, trạng thái cuối cùng sẽ được trả về và có thể được sử dụng để nhanh chóng tạo ra các logits tiếp theo.
  • output_attentions (bool, tùy chọn) — Có trả về các tensor attentions của tất cả các lớp attention hay không. Xem attentions trong phần tensor được trả về để biết thêm chi tiết.
  • output_hidden_states (bool, tùy chọn) — Có trả về trạng thái ẩn (hidden states) của tất cả các lớp hay không. Xem hidden_states trong phần tensor trả về để biết thêm chi tiết.
  • return_dict (bool, tùy chọn) — Có nên trả về một ModelOutput thay vì một tuple thông thường hay không.
  • logits_to_keep (Union[int, torch.Tensor], tùy chọn, mặc định là 0) — Nếu là int, tính logits cho logits_to_keep token cuối. Nếu là 0, tính logits cho tất cả input_ids (trường hợp đặc biệt). Chỉ cần logits của token cuối cho quá trình sinh, và việc chỉ tính cho token đó có thể tiết kiệm bộ nhớ, điều này trở nên khá đáng kể với các chuỗi dài hoặc kích thước từ vựng lớn. Nếu là torch.Tensor, phải là 1 chiều tương ứng với các chỉ số cần giữ trong chiều độ dài chuỗi. Điều này hữu ích khi sử dụng định dạng tensor đóng gói (một chiều duy nhất cho batch và độ dài chuỗi).

Trả về

RwkvCausalLMOutput hoặc tuple(torch.Tensor)

Một RwkvCausalLMOutput hoặc một tuple của torch.Tensor (nếu return_dict=False được truyền hoặc khi config.return_dict=False) bao gồm các thành phần khác nhau tùy thuộc vào cấu hình (RwkvConfig) và đầu vào.

Phương thức forward của RwkvForCausalLM ghi đè lên phương thức đặc biệt __call__.

Mặc dù công thức cho bước truyền tiến cần được định nghĩa bên trong hàm này, người dùng nên gọi instance của Module sau đó thay vì gọi hàm này, vì instance Module sẽ đảm nhận việc thực hiện các bước tiền xử lý và hậu xử lý, trong khi hàm này sẽ lặng lẽ bỏ qua chúng.

  • loss (torch.Tensor có shape (1,), tùy chọn, được trả về khi labels được cung cấp) — Loss của language modeling (cho next-token prediction).

  • logits (torch.Tensor có hình dạng (batch_size, sequence_length, config.vocab_size)) — Điểm dự đoán của đầu mô hình hóa ngôn ngữ (điểm cho mỗi token trong từ vựng trước SoftMax).

  • state (list gồm năm torch.Tensor có hình dạng (batch_size, hidden_size, num_hidden_layers)) — Trạng thái của mô hình tại bước thời gian cuối cùng. Có thể được sử dụng trong phương thức forward với input_ids tiếp theo để tránh việc cung cấp lại input_ids cũ.

  • hidden_states (tuple[torch.Tensor, ...], tuỳ chọn, được trả về khi output_hidden_states=True được truyền vào hoặc khi config.output_hidden_states=True) — Tuple của torch.Tensor (một cho đầu ra của embeddings, nếu mô hình có lớp embedding, + một cho đầu ra của mỗi lớp) có hình dạng (batch_size, sequence_length, hidden_size).

    Trạng thái ẩn của mô hình tại đầu ra của mỗi lớp cùng với các đầu ra embedding ban đầu tùy chọn.

  • attentions (tuple[torch.Tensor, ...], tuỳ chọn, được trả về khi output_attentions=True được truyền vào hoặc khi config.output_attentions=True) — Tuple của torch.Tensor (một cho mỗi lớp) có hình dạng (batch_size, num_heads, sequence_length, sequence_length).

    Trọng số chú ý sau softmax của attention, được sử dụng để tính trung bình có trọng số trong các đầu self-attention.

Ví dụ:

Cơ chế chú ý Rwkv và các công thức đệ quy

Trong một Transformer tự hồi quy truyền thống, attention được viết dưới dạng O=softmax(QKT/d)VO = \hbox{softmax}(QK^{T} / \sqrt{d}) V

với $Q$, KK và VV là các ma trận có hình dạng seq_len x hidden_size được gọi là query, key và value (thực tế chúng là các ma trận lớn hơn có thêm chiều batch và chiều attention head, nhưng chúng ta chỉ quan tâm đến hai chiều cuối cùng, nơi phép nhân ma trận được thực hiện, nên vì sự đơn giản, chúng ta chỉ xét hai chiều đó). Tích QKTQK^{T} sau đó có hình dạng seq_len x seq_len và chúng ta có thể thực hiện phép nhân ma trận với VV để lấy đầu ra OO có cùng hình dạng với các ma trận khác.

Thay softmax bằng giá trị của nó, ta có: Oi=∑j=1ieQiKjT/dVj∑j=1ieQiKjT/dO_{i} = \frac{\sum_{j=1}^{i} e^{Q_{i} K_{j}^{T} / \sqrt{d}} V_{j}}{\sum_{j=1}^{i} e^{Q_{i} K_{j}^{T} / \sqrt{d}}}

Lưu ý rằng các phần tử trong QKTQK^{T} tương ứng với $j > i$ bị che (tổng dừng lại ở j) vì attention không được phép nhìn vào các token tương lai (chỉ nhìn vào các token quá khứ).

Ngược lại, cơ chế chú ý của RWKV được cho bởi Oi=σ(Ri)∑j=1ieWi−j+KjVj∑j=1ieWi−j+KjO_{i} = \sigma(R_{i}) \frac{\sum_{j=1}^{i} e^{W_{i-j} + K_{j}} V_{j}}{\sum_{j=1}^{i} e^{W_{i-j} + K_{j}}}

trong đó RR là một ma trận mới được tác giả gọi là receptance, KK và VV vẫn là key và value ($\sigma$ ở đây là hàm sigmoid). WW là một vector mới đại diện cho vị trí của token và được cho bởi W0=u and Wk=(k−1)w for k≥1W_{0} = u \hbox{ and } W_{k} = (k-1)w \hbox{ for } k \geq 1

với uu và ww các tham số có thể học được gọi là time_first và time_decay tương ứng. Tử số và mẫu số đều có thể được biểu diễn đệ quy. Đặt tên cho chúng là NiN_{i} và DiD_{i} ta có: Ni=eu+KiVi+N^i where N^i=eKi−1Vi−1+ew+Ki−2Vi−2⋯+e(i−2)w+K1V1N_{i} = e^{u + K_{i}} V_{i} + \hat{N}_{i} \hbox{ where } \hat{N}_{i} = e^{K_{i-1}} V_{i-1} + e^{w + K_{i-2}} V_{i-2} \cdots + e^{(i-2)w + K_{1}} V_{1}

sao N^i\hat{N}_{i} (được gọi là numerator_state trong mã) thỏa mãn N^0=0 and N^j+1=eKjVj+ewN^j\hat{N}_{0} = 0 \hbox{ and } \hat{N}_{j+1} = e^{K_{j}} V_{j} + e^{w} \hat{N}_{j}

và Di=eu+Ki+D^i where D^i=eKi−1+ew+Ki−2⋯+e(i−2)w+K1D_{i} = e^{u + K_{i}} + \hat{D}_{i} \hbox{ where } \hat{D}_{i} = e^{K_{i-1}} + e^{w + K_{i-2}} \cdots + e^{(i-2)w + K_{1}}

nên D^i\hat{D}_{i} (được gọi là denominator_state trong mã) thỏa mãn D^0=0 and D^j+1=eKj+ewD^j\hat{D}_{0} = 0 \hbox{ and } \hat{D}_{j+1} = e^{K_{j}} + e^{w} \hat{D}_{j}

Công thức đệ quy thực tế được sử dụng phức tạp hơn một chút, vì để đảm bảo ổn định số, chúng ta không muốn tính lũy thừa của các số lớn. Thông thường, softmax không được tính trực tiếp, mà lũy thừa của số hạng lớn nhất được chia cho cả tử và mẫu: exi∑j=1nexj=exi−M∑j=1nexj−M\frac{e^{x_{i}}}{\sum_{j=1}^{n} e^{x_{j}}} = \frac{e^{x_{i} - M}}{\sum_{j=1}^{n} e^{x_{j} - M}}

với MM là giá trị lớn nhất của tất cả $x_{j}$. Vì vậy, ở đây ngoài việc lưu trạng tử tử số ($\hat{N}$) và trạng tử mẫu số ($\hat{D}$), chúng ta còn theo dõi giá trị lớn nhất của tất cả các số hạng gặp trong các hàm mũ. Do đó, chúng ta thực sự sử dụng N~i=e−MiN^i and D~i=e−MiD^i\tilde{N}_{i} = e^{-M_{i}} \hat{N}_{i} \hbox{ and } \tilde{D}_{i} = e^{-M_{i}} \hat{D}_{i}

được định nghĩa bởi các công thức đệ quy sau: N~0=0 and N~j+1=eKj−qVj+ew+Mj−qN~j where q=max⁡(Kj,w+Mj)\tilde{N}_{0} = 0 \hbox{ and } \tilde{N}_{j+1} = e^{K_{j} - q} V_{j} + e^{w + M_{j} - q} \tilde{N}_{j} \hbox{ where } q = \max(K_{j}, w + M_{j})

và D~0=0 and D~j+1=eKj−q+ew+Mj−qD~j where q=max⁡(Kj,w+Mj)\tilde{D}_{0} = 0 \hbox{ and } \tilde{D}_{j+1} = e^{K_{j} - q} + e^{w + M_{j} - q} \tilde{D}_{j} \hbox{ where } q = \max(K_{j}, w + M_{j})

và $M_{j+1} = q$. Với những giá trị này, chúng ta có thể tính toán Ni=eu+Ki−qVi+eMiN~i where q=max⁡(u+Ki,Mi)N_{i} = e^{u + K_{i} - q} V_{i} + e^{M_{i}} \tilde{N}_{i} \hbox{ where } q = \max(u + K_{i}, M_{i})

và Di=eu+Ki−q+eMiD~i where q=max⁡(u+Ki,Mi)D_{i} = e^{u + K_{i} - q} + e^{M_{i}} \tilde{D}_{i} \hbox{ where } q = \max(u + K_{i}, M_{i})

cuối cùng cho chúng ta Oi=σ(Ri)NiDiO_{i} = \sigma(R_{i}) \frac{N_{i}}{D_{i}}

Update on GitHub