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.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Model ini disumbangkan ke Hugging Face Transformers pada 2023-05-09.

RWKV

Ikhtisar

Model RWKV (versi 4) diusulkan di repo ini

Hal ini mengusulkan penyesuaian pada perhatian Transformer tradisional agar menjadi linear. Dengan cara ini, model dapat digunakan sebagai jaringan rekuren: meneruskan input untuk timestamp 0 dan timestamp 1 secara bersamaan sama dengan meneruskan input pada timestamp 0, kemudian input pada timestamp 1 bersama dengan state dari timestamp 0 (lihat contoh di bawah).

Hal ini dapat lebih efisien daripada Transformer reguler dan dapat menangani kalimat dengan panjang apa pun (bahkan jika model menggunakan panjang konteks tetap untuk pelatihan).

Model ini disumbangkan oleh sgugger. Kode aslinya dapat ditemukan di sini.

Contoh penggunaan

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)

Jika Anda ingin memastikan model berhenti menghasilkan teks ketika '\n\n' terdeteksi, kami merekomendasikan untuk menggunakan kriteria penghentian berikut:

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()])

Catatan

  • Gunakan padding kiri untuk generasi batched. Lihat Sisi padding.

RwkvConfig

kelas 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 )

Parameter

  • vocab_size (int, opsional, default 50277) — Ukuran kosakata model. Menentukan jumlah token berbeda yang dapat direpresentasikan oleh input_ids.
  • context_length (int, opsional, default 1024) — Panjang maksimum sekuens yang dapat digunakan dengan model ini dalam satu forward (penggunaannya dalam mode RNN memungkinkan penggunaan panjang sekuens apa pun).
  • hidden_size (int, opsional, default 4096) — Dimensi dari representasi tersembunyi.
  • num_hidden_layers (int, opsional, default 32) — Jumlah lapisan tersembunyi dalam decoder Transformer.
  • attention_hidden_size (int, opsional) — Dimensi dari hidden states attention. Akan menggunakan hidden_size sebagai nilai default jika tidak disetel.
  • intermediate_size (int, opsional) — Dimensi dari representasi MLP.
  • layer_norm_epsilon (float, opsional, defaultnya 1e-05) — Epsilon yang digunakan oleh lapisan normalisasi lapisan.
  • bos_token_id (int, opsional, default 0) — ID token yang digunakan untuk awal aliran (beginning-of-stream) dalam kosakata.
  • eos_token_id (Union[int, list[int]], opsional, default 0) — ID token yang digunakan untuk end-of-stream dalam kosakata.
  • rescale_every (int, opsional, default 6) — Saat inferensi, hidden states (dan bobot dari lapisan output yang sesuai) dibagi dengan 2 setiap rescale_every lapisan. Jika diatur ke 0 atau bilangan negatif, tidak dilakukan rescale.
  • tie_word_embeddings (bool, opsional, default False) — Apakah akan mengikat bobot embedding sesuai dengan pemetaan tied_weights_keys model.
  • use_cache (bool, opsional, defaultnya True) — Apakah model harus mengembalikan perhatian kunci/nilai terakhir (tidak digunakan oleh semua model). Hanya relevan jika config.is_decoder=True atau ketika model adalah model generatif yang hanya decoder.

Ini adalah kelas konfigurasi untuk menyimpan konfigurasi dari RwkvModel. Kelas ini digunakan untuk menginstansiasi model Rwkv berdasarkan argumen yang ditentukan, yang mendefinisikan arsitektur model. Menginstansiasi konfigurasi dengan nilai default akan menghasilkan konfigurasi yang serupa dengan konfigurasi dari RWKV/rwkv-4-169m-pile

Objek konfigurasi mewarisi dari PreTrainedConfig dan dapat digunakan untuk mengontrol output model. Baca dokumentasi dari PreTrainedConfig untuk informasi lebih lanjut.

Contoh:

>>> 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

kelas transformers.RwkvModel

< >

( config: RwkvConfig )

Parameter

  • config (RwkvConfig) — Kelas konfigurasi model dengan semua parameter model. Inisialisasi dengan file konfigurasi tidak memuat bobot yang terkait dengan model, hanya konfigurasinya. Lihat metode from_pretrained() untuk memuat bobot model.

Model Rwkv polos yang menghasilkan hidden-states mentah tanpa head spesifik di atasnya.

Model ini mewarisi dari PreTrainedModel. Periksa dokumentasi kelas induk untuk metode generik yang diimplementasikan oleh pustaka untuk semua model (seperti mengunduh atau menyimpan, mengubah ukuran embedding input, memangkas kepala, dll.)

Model ini juga merupakan subclass dari torch.nn.Module PyTorch. Gunakan sebagai PyTorch Module biasa dan merujuk ke dokumentasi PyTorch untuk semua hal yang berkaitan dengan penggunaan dan perilaku umum.

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)

Parameter

  • input_ids (torch.LongTensor dengan bentuk (batch_size, input_ids_length)) — input_ids_length = sequence_length jika past_key_values adalah None jika tidak past_key_values.get_seq_length() (sequence_length dari input past key value states). Indeks token urutan input dalam kosakata.

    Jika past_key_values digunakan, hanya input_ids yang belum memiliki nilai masa lalunya yang dihitung yang harus diteruskan sebagai input_ids.

    Indeks dapat diperoleh menggunakan AutoTokenizer. Lihat PreTrainedTokenizer.encode() dan PreTrainedTokenizer.call() untuk detailnya.

    Apa itu input ID?

  • attention_mask (torch.LongTensor dengan bentuk (batch_size, sequence_length), opsional) — Mask untuk menghindari eksekusi attention pada indeks token padding. Nilai mask dipilih dari [0, 1]:
    • 1 untuk token yang tidak dimasker,
    • 0 untuk token yang dimasker.

    Apa itu attention mask?

  • inputs_embeds (torch.Tensor dengan bentuk (batch_size, sequence_length, hidden_size), opsional) — Secara opsional, alih-alih meneruskan input_ids, Anda dapat memilih untuk langsung meneruskan representasi tertanam. Hal ini berguna jika Anda ingin memiliki kendali lebih atas cara mengonversi indeks input_ids menjadi vektor terkait, dibandingkan dengan matriks pencarian penanaman internal model.
  • state (tuple dari lima torch.Tensor dengan bentuk (batch_size, hidden_size, num_hidden_layers), opsional) — Jika diberikan, model menggunakan state sebelumnya di semua blok (yang akan menghasilkan output untuk input_ids yang diberikan seolah-olah model menambahkan state_input_ids + input_ids sebagai konteks).
  • use_cache (bool, opsional) — Jika diset ke True, state terakhir akan dikembalikan dan dapat digunakan untuk dengan cepat menghasilkan logits berikutnya.
  • output_attentions (bool, opsional) — Apakah akan mengembalikan tensor attentions dari semua lapisan attention. Lihat attentions di bawah tensor yang dikembalikan untuk detail lebih lanjut.
  • output_hidden_states (bool, opsional) — Apakah akan mengembalikan hidden states dari semua lapisan. Lihat hidden_states di bawah tensor yang dikembalikan untuk detail lebih lanjut.
  • return_dict (bool, opsional) — Apakah akan mengembalikan ModelOutput alih-alih tuple biasa.

Mengembalikan

RwkvOutput atau tuple(torch.Tensor)

A RwkvOutput atau tuple dari torch.Tensor (jika return_dict=False diberikan atau ketika config.return_dict=False) yang terdiri dari berbagai elemen tergantung pada konfigurasi (RwkvConfig) dan input.

Metode forward dari RwkvModel menimpa metode khusus __call__.

Meskipun resep untuk forward pass perlu didefinisikan di dalam fungsi ini, sebaiknya panggil instance Module setelahnya alih-alih fungsi ini, karena yang pertama menangani langkah-langkah pra-pemrosesan dan pasca-pemrosesan, sedangkan yang kedua mengabaikannya secara diam-diam.

  • last_hidden_state (torch.Tensor dengan bentuk (batch_size, sequence_length, hidden_size), opsional) — Urutan hidden-states pada keluaran lapisan terakhir model.

  • state (list berisi lima torch.Tensor dengan bentuk (batch_size, hidden_size, num_hidden_layers)) — State model pada langkah waktu terakhir. Dapat digunakan dalam metode forward bersama input_ids berikutnya untuk menghindari penyediaan input_ids lama.

  • hidden_states (tuple[torch.Tensor, ...], opsional, dikembalikan ketika output_hidden_states=True dilewatkan atau ketika config.output_hidden_states=True) — Tuple dari torch.Tensor (satu untuk output dari embeddings, jika model memiliki lapisan embedding, + satu untuk output dari setiap lapisan) dengan bentuk (batch_size, sequence_length, hidden_size).

    Hidden-states model pada output setiap layer ditambah output embedding awal yang opsional.

  • attentions (tuple[torch.Tensor, ...], opsional, dikembalikan saat output_attentions=True dilewatkan atau saat config.output_attentions=True) — Tuple dari torch.Tensor (satu untuk setiap layer) dengan bentuk (batch_size, num_heads, sequence_length, sequence_length).

    Bobot perhatian setelah softmax perhatian, digunakan untuk menghitung rata-rata berbobot di kepala perhatian diri (self-attention).

RwkvLMHeadModel

kelas transformers.RwkvForCausalLM

< >

( config: RwkvConfig )

Parameter

  • config (RwkvConfig) — Kelas konfigurasi model dengan semua parameter model. Inisialisasi dengan file konfigurasi tidak memuat bobot yang terkait dengan model, hanya konfigurasinya. Lihat metode from_pretrained() untuk memuat bobot model.

Transformer Model RWKV dengan kepala pemodelan bahasa di atasnya (lapisan linear dengan bobot yang terikat ke embedding input).

Model ini mewarisi dari PreTrainedModel. Periksa dokumentasi kelas induk untuk metode generik yang diimplementasikan oleh pustaka untuk semua model (seperti mengunduh atau menyimpan, mengubah ukuran embedding input, memangkas kepala, dll.)

Model ini juga merupakan subclass dari torch.nn.Module PyTorch. Gunakan sebagai PyTorch Module biasa dan merujuk ke dokumentasi PyTorch untuk semua hal yang berkaitan dengan penggunaan dan perilaku umum.

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)

Parameter

  • input_ids (torch.LongTensor dengan bentuk (batch_size, input_ids_length)) — input_ids_length = sequence_length jika past_key_values adalah None jika tidak past_key_values.get_seq_length() (sequence_length dari input past key value states). Indeks token urutan input dalam kosakata.

    Jika past_key_values digunakan, hanya input_ids yang belum memiliki nilai masa lalunya yang dihitung yang harus diteruskan sebagai input_ids.

    Indeks dapat diperoleh menggunakan AutoTokenizer. Lihat PreTrainedTokenizer.encode() dan PreTrainedTokenizer.call() untuk detailnya.

    Apa itu input ID?

  • attention_mask (torch.LongTensor dengan bentuk (batch_size, sequence_length), opsional) — Mask untuk menghindari eksekusi attention pada indeks token padding. Nilai mask dipilih dari [0, 1]:
    • 1 untuk token yang tidak dimasker,
    • 0 untuk token yang dimasker.

    Apa itu attention mask?

  • inputs_embeds (torch.Tensor dengan bentuk (batch_size, sequence_length, hidden_size), opsional) — Secara opsional, alih-alih meneruskan input_ids, Anda dapat memilih untuk langsung meneruskan representasi tertanam. Hal ini berguna jika Anda ingin memiliki kendali lebih atas cara mengonversi indeks input_ids menjadi vektor terkait, dibandingkan dengan matriks pencarian penanaman internal model.
  • state (tuple dari lima torch.Tensor dengan bentuk (batch_size, hidden_size, num_hidden_layers), opsional) — Jika diberikan, model menggunakan state sebelumnya di semua blok (yang akan menghasilkan output untuk input_ids yang diberikan seolah-olah model menambahkan state_input_ids + input_ids sebagai konteks).
  • labels (torch.LongTensor dengan bentuk (batch_size, sequence_length), opsional) — Label untuk pemodelan bahasa. Perhatikan bahwa label digeser di dalam model, yaitu Anda dapat mengatur labels = input_ids Indeks dipilih dalam [-100, 0, ..., config.vocab_size] Semua label yang diatur ke -100 diabaikan (dipertahankan), loss hanya dihitung untuk label dalam [0, ..., config.vocab_size]
  • use_cache (bool, opsional) — Jika diset ke True, state terakhir akan dikembalikan dan dapat digunakan untuk dengan cepat menghasilkan logits berikutnya.
  • output_attentions (bool, opsional) — Apakah akan mengembalikan tensor attentions dari semua lapisan attention. Lihat attentions di bawah tensor yang dikembalikan untuk detail lebih lanjut.
  • output_hidden_states (bool, opsional) — Apakah akan mengembalikan hidden states dari semua lapisan. Lihat hidden_states di bawah tensor yang dikembalikan untuk detail lebih lanjut.
  • return_dict (bool, opsional) — Apakah akan mengembalikan ModelOutput alih-alih tuple biasa.
  • logits_to_keep (Union[int, torch.Tensor], opsional, default 0) — Jika berupa int, hitung logits untuk logits_to_keep token terakhir. Jika 0, hitung logits untuk semua input_ids (kasus khusus). Hanya logits token terakhir yang diperlukan untuk generasi, dan menghitungnya hanya untuk token tersebut dapat menghemat memori, yang menjadi cukup signifikan untuk urutan panjang atau ukuran kosakata besar. Jika berupa torch.Tensor, harus 1D yang sesuai dengan indeks yang akan dipertahankan pada dimensi panjang urutan. Ini berguna saat menggunakan format tensor terpadu (satu dimensi untuk batch dan panjang urutan).

Mengembalikan

RwkvCausalLMOutput atau tuple(torch.Tensor)

RwkvCausalLMOutput atau tuple dari torch.Tensor (jika return_dict=False diteruskan atau ketika config.return_dict=False) yang terdiri dari berbagai elemen tergantung pada konfigurasi (RwkvConfig) dan input.

Metode forward dari RwkvForCausalLM menimpa metode khusus __call__.

Meskipun resep untuk forward pass perlu didefinisikan di dalam fungsi ini, sebaiknya panggil instance Module setelahnya alih-alih fungsi ini, karena yang pertama menangani langkah-langkah pra-pemrosesan dan pasca-pemrosesan, sedangkan yang kedua mengabaikannya secara diam-diam.

  • loss (torch.Tensor dengan bentuk (1,), opsional, dikembalikan saat labels disediakan) — Loss pemodelan bahasa (untuk prediksi token berikutnya).

  • logits (torch.Tensor dengan bentuk (batch_size, sequence_length, config.vocab_size)) — Skor prediksi dari kepala pemodelan bahasa (skor untuk setiap token kosakata sebelum SoftMax).

  • state (list berisi lima torch.Tensor dengan bentuk (batch_size, hidden_size, num_hidden_layers)) — State model pada langkah waktu terakhir. Dapat digunakan dalam metode forward bersama input_ids berikutnya untuk menghindari penyediaan input_ids lama.

  • hidden_states (tuple[torch.Tensor, ...], opsional, dikembalikan ketika output_hidden_states=True dilewatkan atau ketika config.output_hidden_states=True) — Tuple dari torch.Tensor (satu untuk output dari embeddings, jika model memiliki lapisan embedding, + satu untuk output dari setiap lapisan) dengan bentuk (batch_size, sequence_length, hidden_size).

    Hidden-states model pada output setiap layer ditambah output embedding awal yang opsional.

  • attentions (tuple[torch.Tensor, ...], opsional, dikembalikan saat output_attentions=True dilewatkan atau saat config.output_attentions=True) — Tuple dari torch.Tensor (satu untuk setiap layer) dengan bentuk (batch_size, num_heads, sequence_length, sequence_length).

    Bobot perhatian setelah softmax perhatian, digunakan untuk menghitung rata-rata berbobot di kepala perhatian diri (self-attention).

Contoh:

Perhatian Rwkv dan rumus rekurens

Pada Transformer auto-regressive tradisional, attention ditulis sebagai O=softmax(QKT/d)VO = \hbox{softmax}(QK^{T} / \sqrt{d}) V

dengan $Q$, KK dan VV adalah matriks dengan bentuk seq_len x hidden_size yang disebut query, key, dan value (sebenarnya ini adalah matriks yang lebih besar dengan dimensi batch dan dimensi attention head, tetapi kami hanya tertarik pada dua dimensi terakhir, yaitu tempat perkalian matriks dilakukan, sehingga demi kesederhanaan kami hanya mempertimbangkan dua dimensi tersebut). Hasil perkalian QKTQK^{T} lalu memiliki bentuk seq_len x seq_len dan kami dapat melakukan perkalian matriks dengan VV untuk mendapatkan output OO dengan bentuk yang sama seperti yang lain.

Menggantikan softmax dengan nilainya menghasilkan: 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}}}

Perhatikan bahwa entri dalam QKTQK^{T} yang sesuai dengan $j > i$ dimasker (penjumlahan berhenti di j) karena attention tidak diizinkan melihat token masa depan (hanya token masa lalu).

Sebagai perbandingan, perhatian RWKV diberikan oleh 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}}}

di mana RR adalah matriks baru yang disebut receptance oleh penulisnya, KK dan VV tetap menjadi key dan value ($\sigma$ di sini adalah fungsi sigmoid). WW adalah vektor baru yang merepresentasikan posisi token dan diberikan oleh W0=u and Wk=(k−1)w for k≥1W_{0} = u \hbox{ and } W_{k} = (k-1)w \hbox{ for } k \geq 1

dengan uu dan ww parameter yang dapat dipelajari, yang disebut dalam kode sebagai time_first dan time_decay masing-masing. Pembilang dan penyebut keduanya dapat diekspresikan secara rekursif. Dengan menamainya NiN_{i} dan DiD_{i} kita memiliki: 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}

sehingga N^i\hat{N}_{i} (disebut numerator_state dalam kode) memenuhi 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}

dan 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}}

sehingga D^i\hat{D}_{i} (disebut denominator_state dalam kode) memenuhi 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}

Rumus rekuren yang sebenarnya digunakan sedikit lebih kompleks, karena untuk stabilitas numerik kita tidak ingin menghitung eksponen dari angka-angka besar. Biasanya, softmax tidak dihitung apa adanya, melainkan eksponen dari suku maksimum dibagi pada pembilang dan penyebut: 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}}

dengan MM sebagai maksimum dari semua $x_{j}$. Jadi, di sini selain menyimpan state pembilang ($\hat{N}$) dan state penyebut ($\hat{D}$), kita juga melacak maksimum dari semua suku yang ditemui dalam eksponensial. Jadi, kita sebenarnya menggunakan 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}

didefinisikan oleh rumus rekuren berikut: 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})

dan 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})

dan $M_{j+1} = q$. Dengan itu, kita dapat menghitung 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})

dan 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})

yang akhirnya menghasilkan Oi=σ(Ri)NiDiO_{i} = \sigma(R_{i}) \frac{N_{i}}{D_{i}}

Update on GitHub