
    h                        S SK JrJr  S SKJr  S SKJr  S SKJrJ	r	J
r
JrJr  S SKrS SKrS SKJr  S SKrS SKJrJr  S SKJr  \" S\\5      rS	\\\\4      S
\SS4S jrS\\\4   S\ 4S jr! S)S\\\\\\4      4   S\S\
\\\\	4         S\\\4   4S jjr" S)S\\\\\\4      4   S\S\
\\\\	4         S\S\\\4   4
S jjr#S\\\\\\\4      4      S\\\\\\\4      4      4S jr$ S*S\S\
\   S\
\   S\4S jjr% S*S\S\
\   S\
\   S\4S jjr&S\\\4   S\\\4   4S jr'S\\\4   S\\\4   4S jr( " S S5      r)S\RT                  S\S\RT                  4S  jr+S\RT                  S\S\RT                  4S! jr, S+S\S\S"\S#\
\\\4      S\4
S$ jjr- S)S\S%\S#\
\\\4      S\4S& jjr.S\\\4   S\ 4S' jr/S\\\4   S\\\4   4S( jr0g),    )defaultdictdeque)Sequence)	takewhile)AnyCallableOptionalTypeVarUnionN)DatasetDatasetDict)PreTrainedTokenizerBaseDatasetTypemessages
num_imagesreturnc                    SnU  H  nUS   S:X  a(  [        US   [        5      (       a  SUS   S./US'   M2  M4  US   S:X  ak  [        US   [        5      (       a"  U(       d  SS	0/U-  n/ UQSUS   S.PUS'   S
nMw  [        US   [        5      (       a  U(       a  SUS   S./US'   M  M  M  US   S:X  a(  [        US   [        5      (       a  SUS   S./US'   M  M  [        SUS    S35      e   g)a  
Convert messages into a structured multimodal format if needed.

Each message's content is transformed from a raw string into a list of typed parts. The first user message is
prefixed with an image placeholder, while all other user and assistant messages are wrapped as text entries.

Args:
    messages (`list[dict[str, Any]]`):
        Messages with `"role"` and `"content"`. Content may be a raw string before transformation.
    num_images (`int`):
        Number of images to include in the first user message. This is used to determine how many image
        placeholders to add.

Example:
```python
# Input
[
    {"role": "user", "content": "What's in this image?"},
    {"role": "assistant", "content": "It looks like a cat."},
]

# Output (num_images=1)
[
    {"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "What's in this image?"}]},
    {"role": "assistant", "content": [{"type": "text", "text": "It looks like a cat."}]},
]
```
Frolesystemcontenttext)typer   userr   imageT	assistantzInvalid role in message: z,. Expected 'user', 'assistant', or 'system'.N)
isinstancestr
ValueError)r   r   image_includedmessageplaceholderss        H/home/james-whalen/.local/lib/python3.13/site-packages/trl/data_utils.pyprepare_multimodal_messagesr#      s.   : N6?h&'),c22/5wy?Q&R%S	" 3V_&'),c22>!' 12Z?%b|%bfgV_N`5a%b	"!%GI.44/5wy?Q&R%S	" :H4V_+'),c22/5wy?Q&R%S	" 3 88IIuvww     examplec                    / SQnU R                  5        Vs1 s H  o"U;   d  M
  UiM     nnU(       aP  UR                  5       nX   n[        U[        5      (       a'  US   n[        U[        5      (       a  SU;   a  SU;   a  ggs  snf )a	  
Check if the example is in a conversational format.

Args:
    example (`dict[str, Any]`):
        A single data entry of a dataset. The example can have different keys depending on the dataset type.

Returns:
    `bool`:
        `True` if the data is in a conversational format, `False` otherwise.

Examples:

```python
>>> example = {"prompt": [{"role": "user", "content": "What color is the sky?"}]}
>>> is_conversational(example)
True

>>> example = {"prompt": "The sky is"}
>>> is_conversational(example)
False
```
)promptchosenrejected
completionr   r   r   r   TF)keyspopr   listdict)r%   supported_keyskeyexample_keysmaybe_messagesmaybe_messages         r"   is_conversationalr4   O   s    0 PN#*<<>K>CN5JC>LK   nd++*1-M-..6]3Jy\iOi Ls
   	BB	tokenizertoolsc           
         / SQnU R                  5        Vs1 s H  oUU;   d  M
  UiM     nnUS1S1SS11 SkSS11 Sk4;  a  [        S	U 35      eSU ;   a  UR                  " U S   4US
S.UD6nSU ;   aJ  U S   S   S   nUS:X  a  Sn	S
n
OUS:X  a  S
n	Sn
O[        SU 35      eUR                  " U S   4UU
S
U	S.UD6nSU ;   Ga'  SU ;   aZ  UR                  " U S   U S   -   4US
S.UD6nSR	                  S [        S [        WU5      5       5       5      nU[        U5      S nSU ;   a`  SU ;   aZ  UR                  " U S   U S   -   4US
S.UD6nSR	                  S [        S [        WU5      5       5       5      nU[        U5      S nSU ;   aZ  UR                  " U S   U S   -   4US
S.UD6nSR	                  S [        S [        WU5      5       5       5      nU[        U5      S nO>SU ;   a  UR                  " U S   4US
S.UD6nSU ;   a  UR                  " U S   4US
S.UD6n0 nSU ;   a  WUS'   SU ;   a  WUS'   SU ;   a  WUS'   SU ;   a  WUS'   SU ;   a  WUS'   SU ;   a  U S   US'   U$ s  snf )z
Apply a chat template to a conversational example along with the schema for a list of functions in `tools`.

For more details, see [`maybe_apply_chat_template`].
)r'   r(   r)   r*   r   labelr   r'   r*   >   r(   r'   r)   r(   r)   >   r8   r'   r*   zInvalid keys in the example: F)r6   tokenizer   r   Tr   z"Invalid role in the last message: )r6   continue_final_messager9   add_generation_prompt c              3   *   #    U  H	  u  pUv   M     g 7fN .0x_s      r"   	<genexpr>&apply_chat_template.<locals>.<genexpr>   s     i+h41Q+h   c                     U S   U S   :H  $ Nr      r@   rC   s    r"   <lambda>%apply_chat_template.<locals>.<lambda>       qtqt|r$   Nc              3   *   #    U  H	  u  pUv   M     g 7fr?   r@   rA   s      r"   rE   rF      s     k+j41Q+jrG   c                     U S   U S   :H  $ rI   r@   rK   s    r"   rL   rM      rN   r$   c              3   *   #    U  H	  u  pUv   M     g 7fr?   r@   rA   s      r"   rE   rF      s     m+l41Q+lrG   c                     U S   U S   :H  $ rI   r@   rK   s    r"   rL   rM      rN   r$   r   r8   )r+   KeyErrorapply_chat_templater   joinr   ziplen)r%   r5   r6   template_kwargsr/   r0   r1   r   	last_roler<   r;   r'   prompt_chosenr(   prompt_rejectedr)   prompt_completionr*   outputs                      r"   rT   rT   x   sp    YN#*<<>K>CN5JC>LK		
	< (	:)  6|nEFF W001DuE\auetu 7H%b)&1	$(!%*"+%$)!%)"A)MNN..H
#9"7
 
 7w%99!GH$55=BUVeM WWi95KSQWYfMg+hiiF"3v;=1F X%8';;!GJ$77?DuXgO WWk95KSQWYhMi+jkkF&s6{}5H7" ) = =!GL$99!AFQV!Zi! WWm95KSQWYjMk+lmmF*3v;=9Jw22783DuE\auetuF  44
#+05DSH
 FW!v7!x7!xW%zw)|'!'*wMi Ls
   	I4I4rX   c                 @    [        U 5      (       a  [        XU40 UD6$ U $ )a&	  
If the example is in a conversational format, apply a chat template to it.

Args:
    example (`dict[str, list[dict[str, str]]`):
        Dictionary representing a single data entry of a conversational dataset. Each data entry can have different
        keys depending on the dataset type. The supported dataset types are:

            - Language modeling dataset: `"messages"`.
            - Prompt-only dataset: `"prompt"`.
            - Prompt-completion dataset: `"prompt"` and `"completion"`.
            - Preference dataset: `"prompt"`, `"chosen"`, and `"rejected"`.
            - Preference dataset with implicit prompt: `"chosen"` and `"rejected"`.
            - Unpaired preference dataset: `"prompt"`, `"completion"`, and `"label"`.

        For keys `"messages"`, `"prompt"`, `"chosen"`, `"rejected"`, and `"completion"`, the values are lists of
        messages, where each message is a dictionary with keys `"role"` and `"content"`.
    tokenizer (`PreTrainedTokenizerBase`):
        Tokenizer to apply the chat template with.
    tools (`list[Union[dict, Callable]]` or `None`, *optional*, defaults to `None`):
        A list of tools (callable functions) that will be accessible to the model. If the template does not support
        function calling, this argument will have no effect.
    **template_kwargs (`Any`, *optional*):
        Additional kwargs to pass to the template renderer. Will be accessible by the chat template.

Returns:
    `dict[str, str]`:
        Formatted example with the chat template applied.

Notes:
    - This function does not alter the keys, except for Language modeling dataset, where `"messages"` is replaced
    by `"text"`.

    - In case of prompt-only data, if the last role is `"user"`, the generation prompt is added to the prompt.
    Else, if the last role is `"assistant"`, the final message is continued.

Example:

```python
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-128k-instruct")
>>> example = {
...     "prompt": [{"role": "user", "content": "What color is the sky?"}],
...     "completion": [{"role": "assistant", "content": "It is blue."}],
... }
>>> apply_chat_template(example, tokenizer)
{'prompt': '<|user|>\nWhat color is the sky?<|end|>\n<|assistant|>\n', 'completion': 'It is blue.<|end|>\n'}
```
)r4   rT   )r%   r5   r6   rX   s       r"   maybe_apply_chat_templater_      s'    p !!"7uPPPr$   examplesc                 |    [        U S   5      nU S   U S   -   S/U-  S/U-  -   S.nSU ;   a  U S   U S   -   US'   U$ )Nr(   r)   TF)r*   r8   r'   )rW   )r`   
batch_sizenew_rowss      r"   _unpair_rowrd     sh    Xh'(Jx(8J+??*$w';;H 8%h/(82DDOr$   datasetnum_procdescc                 2    U R                  [        SSS/XS9$ )a  
Unpair a preference dataset.

Args:
    dataset (`Dataset` or `DatasetDict`):
        Preference dataset to unpair. The dataset must have columns `"chosen"`, `"rejected"` and optionally
        `"prompt"`.
    num_proc (`int` or `None`, *optional*, defaults to `None`):
        Number of processes to use for processing the dataset.
    desc (`str` or `None`, *optional*, defaults to `None`):
        Meaningful description to be displayed alongside with the progress bar while mapping examples.

Returns:
    `Dataset`: The unpaired preference dataset.

Example:

```python
>>> from datasets import Dataset

>>> dataset_dict = {
...     "prompt": ["The sky is", "The sun is"],
...     "chosen": [" blue.", "in the sky."],
...     "rejected": [" green.", " in the sea."],
... }
>>> dataset = Dataset.from_dict(dataset_dict)
>>> dataset = unpair_preference_dataset(dataset)
>>> dataset
Dataset({
    features: ['prompt', 'completion', 'label'],
    num_rows: 4
})

>>> dataset[0]
{'prompt': 'The sky is', 'completion': ' blue.', 'label': True}
```
Tr(   r)   )batchedremove_columnsrf   rg   )maprd   )re   rf   rg   s      r"   unpair_preference_datasetrl   %  s"    P ;;{D(JAWbj;vvr$   c                     [        U [        5      (       a*  U [        U R                  5       5      S      R                  nOU R                  nSU;   a  SU;   a
  [        XUS9$ U $ )aj  
Unpair a preference dataset if it is paired.

Args:
    dataset (`Dataset` or `DatasetDict`):
        Preference dataset to unpair. The dataset must have columns `"chosen"`, `"rejected"` and optionally
        `"prompt"`.
    num_proc (`int` or `None`, *optional*, defaults to `None`):
        Number of processes to use for processing the dataset.
    desc (`str` or `None`, *optional*, defaults to `None`):
        Meaningful description to be displayed alongside with the progress bar while mapping examples.

Returns:
    `Dataset` or `DatasetDict`: The unpaired preference dataset if it was paired, otherwise the original dataset.

Example:

```python
>>> from datasets import Dataset

>>> dataset_dict = {
...     "prompt": ["The sky is", "The sun is"],
...     "chosen": [" blue.", "in the sky."],
...     "rejected": [" green.", " in the sea."],
... }
>>> dataset = Dataset.from_dict(dataset_dict)
>>> dataset = unpair_preference_dataset(dataset)
>>> dataset
Dataset({
    features: ['prompt', 'completion', 'label'],
    num_rows: 4
})

>>> dataset[0]
{'prompt': 'The sky is', 'completion': ' blue.', 'label': True}
```
r   r(   r)   )rf   rg   )r   r   r-   r+   column_namesrl   )re   rf   rg   rn   s       r"   maybe_unpair_preference_datasetro   P  s^    P ';''tGLLN3A67DD++<J,$>($OOr$   c           	          [        [        [        U S   5      [        U S   5      5      5       H+  nU S   U   U S   U   :w  d  M  U S   US-
     S:X  a  US-  n  O   U S   SW U S   US U S   US S.$ )z
Extracts the shared prompt from a preference data example, where the prompt is implicit within both the chosen and
rejected completions.

For more details, see [`maybe_extract_prompt`].
r(   r)   rJ    N)r'   r(   r)   )rangeminrW   )r%   idxs     r"   extract_promptru     s     SWX./WZ5H1IJK8S!WZ%8%==x q)S0q	 L (#DS)(#CD)J'- r$   c                     SU ;  d  SU ;  a  U $ SU ;   a>  [        SU S   05      n[        SU S   05      nU(       a  U(       d  U(       d	  U(       d  U $ [        U S   U S   S.5      $ )a  
Extracts the shared prompt from a preference data example, where the prompt is implicit within both the chosen and
rejected completions.

If the example already contains a `"prompt"` key, the function returns the example as is. Else, the function
identifies the longest common sequence (prefix) of conversation turns between the "chosen" and "rejected"
completions and extracts this as the prompt. It then removes this prompt from the respective "chosen" and
"rejected" completions.

Args:
    example (`dict[str, list]`):
        A dictionary representing a single data entry in the preference dataset. It must contain the keys
        `"chosen"` and `"rejected"`, where each value is either conversational or standard (`str`).

Returns:
    `dict[str, list]`: A dictionary containing:
        - `"prompt"`: The longest common prefix between the "chosen" and "rejected" completions.
        - `"chosen"`: The remainder of the "chosen" completion, with the prompt removed.
        - `"rejected"`: The remainder of the "rejected" completion, with the prompt removed.

Examples:

```python
>>> example = {
...     "chosen": [
...         {"role": "user", "content": "What color is the sky?"},
...         {"role": "assistant", "content": "It is blue."},
...     ],
...     "rejected": [
...         {"role": "user", "content": "What color is the sky?"},
...         {"role": "assistant", "content": "It is green."},
...     ],
... }
>>> extract_prompt(example)
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}],
 'chosen': [{'role': 'assistant', 'content': 'It is blue.'}],
 'rejected': [{'role': 'assistant', 'content': 'It is green.'}]}
```

Or, with the `map` method of `datasets.Dataset`:

```python
>>> from trl import extract_prompt
>>> from datasets import Dataset

>>> dataset_dict = {
...     "chosen": [
...         [
...             {"role": "user", "content": "What color is the sky?"},
...             {"role": "assistant", "content": "It is blue."},
...         ],
...         [
...             {"role": "user", "content": "Where is the sun?"},
...             {"role": "assistant", "content": "In the sky."},
...         ],
...     ],
...     "rejected": [
...         [
...             {"role": "user", "content": "What color is the sky?"},
...             {"role": "assistant", "content": "It is green."},
...         ],
...         [
...             {"role": "user", "content": "Where is the sun?"},
...             {"role": "assistant", "content": "In the sea."},
...         ],
...     ],
... }
>>> dataset = Dataset.from_dict(dataset_dict)
>>> dataset = dataset.map(extract_prompt)
>>> dataset[0]
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}],
 'chosen': [{'role': 'assistant', 'content': 'It is blue.'}],
 'rejected': [{'role': 'assistant', 'content': 'It is green.'}]}
```
r(   r)   r'   )r(   r)   )r4   ru   )r%   chosen_convprompt_convs      r"   maybe_extract_promptry     sq    d w*G";7'783D(EF'783D(EFK[NWX%6GJDWXYYr$   c                   8    \ rS rSrSrS\4S jrS rS rS r	Sr
g	)
_SegmentTreei  a  
A segment tree data structure that, when initialized as `_SegmentTree(maxval)`, efficiently finds the next larger
value for a given input within the range [1, maxval].

See [Fewer Truncations Improve Language Modeling](https://arxiv.org/abs/2404.10830) for more details.
maxvalc                 v    Xl         SUS-
  R                  5       -  U l        S/SU R                  -  -  U l        g )NrJ   r      )r|   
bit_length	tree_sizetree)selfr|   s     r"   __init___SegmentTree.__init__  s7    vz5577C1t~~-.	r$   c                    SUs=:  a  U R                   ::  d   e   eU R                  U-   S-
  nXR                  U'   US:  aJ  US-  nU R                  US-     U R                  US-  S-      pCX4:  a  UOUU R                  U'   US:  a  MI  g g rI   r|   r   r   r   valileftrights        r"   add_SegmentTree.add   s    3%$++%%%%%NNS 1$		!!e!GA))AF+TYYQ!|-D%#'=4eDIIaL	 !er$   c                    SUs=:  a  U R                   ::  d   e   eU R                  U-   S-
  nSU R                  U'   US:  aJ  US-  nU R                  US-     U R                  US-  S-      pCX4:  a  UOUU R                  U'   US:  a  MI  g g rI   r   r   s        r"   remove_SegmentTree.remove
  s    3%$++%%%%%NNS 1$		!!e!GA))AF+TYYQ!|-D%#'=4eDIIaL	 !er$   c                     SUs=:  a  U R                   ::  d   e   eSnX R                  :  a5  U R                  US-     U:  a  US-  nOUS-  S-   nX R                  :  a  M5  U R                  U   $ rI   r   )r   r   r   s      r"   search_SegmentTree.search  su    3%$++%%%%%.. yya C'F!VqL	 .. 
 yy|r$   )r|   r   r   N)__name__
__module____qualname____firstlineno____doc__intr   r   r   r   __static_attributes__r@   r$   r"   r{   r{     s"    /s /<<r$   r{   
seq_lengthc                 	   / nSn[        U R                  5       H  u  pE[        R                  R	                  UR
                  5      (       d.  [        R                  R                  UR
                  5      (       a  [        R                  " USU5      nUc  UnUR                  U5        M     [        R                  R                  X R                  S9n [        R                  " [!        U 5      5      nUc   e[        R"                  " X   5      R%                  5       nU R'                  SU5      n [        R(                  " Xv5      nUR+                  SSS9n[-        U5      nUR/                  U5        [1        [2        5      n	/ n
[5        UR7                  S5      R9                  5       UR7                  S5      R9                  5       5       H  u  pUR;                  U5      nX:  a  X   R=                  5       nO/ SS.nU
R                  U5        US	   R                  U5        US
==   U-  ss'   X:  a  X   (       d  UR?                  U5        X-
  nX   R                  U5        US:  d  M  UR/                  U5        M     [        R@                  " X
 VVs/ s H  oS	     H  oPM     M     snn5      n [        RB                  " S/U
 Vs/ s H  oS
   PM	     sn-   5      n[        RD                  " U5      n[G        S U R                   5       5      (       d   eU S   RH                  S   nU RK                  S5      n [        RL                  R                  [        RD                  " S/U
 Vs/ s H  n[!        US	   5      PM     sn-   [        RN                  S9U5      n/ nU R                   H  nURH                  S   n[        R                  R	                  UR
                  5      (       d.  [        R                  R                  UR
                  5      (       aX  URP                  R
                  RS                  5       n[        U5      R                  URU                  U5      URV                  5      nUR                  U5        M     [        R                  R                  X'/-   U R                  S/-   S9$ s  snnf s  snf s  snf )zEPack sequences in a pyarrow Table using Best Fit Decreasing strategy.Nr   namesseq_lengths
descending)byrJ   )idslengthr   r   c              3   >   #    U  H  oR                   S :H  v   M     g7f)rJ   N)
num_chunks)rB   columns     r"   rE   _pack_bfd.<locals>.<genexpr>Q  s      -=6Q-=s   dtype),	enumeratecolumnspyarrowtypesis_listr   is_large_listpc
list_sliceappendpaTablefrom_arraysrn   nparangerW   list_value_lengthcombine_chunksappend_columnmake_structsortr{   r   r   r   rV   fieldto_numpyr   popleftr   takearraycumsumallchunksdrop_columns	ListArrayint32offsetsto_pandas_dtypeastypevalues)r`   r   r   list_column_idxrt   r   r   lengthssegment_treespace_to_binbinsr   spacebinid_r   r   s                    r"   	_pack_bfdr     s   GO !1!12==  --1L1LV[[1Y1Y]]61j9F&"%v 3 xx##G3H3H#IH
))CM
"C&&&""8#<=LLNG%%mW=HnnW*Gll<Al.G
+LZ u%L D7==+446a8H8Q8Q8ST##F+%--/C *CKKE
#Hl&9&""3'19U#' U* wwx!L#U###!LMHhhst<t(mt<<=Gii G -5-=-=     }%,,Q/G$$]3Hll&&ryy!SW7XSWCCJSW7X1X`b`h`h'ikrsGG""q!88FKK((BHH,B,B6;;,O,ONN''779E&\--gnnU.CV]]SFv # 88) 38;P;PTaSb;bcc' "M< 8Ys   R8R>
-Sc                 
   / nU R                    GHJ  n[        R                  R                  UR                  5      (       d.  [        R                  R                  UR                  5      (       a  [        U[        R                  5      (       a  UR                  5       nUR                  UR                  pTXTS   R                  5       US   R                  5        n[        U5      nUR                  R                  5       n[        R                   " SXaUS9n[        R"                  " XF/45      n[	        U5      R%                  XE5      nUR'                  U5        GMM     [        R(                  R%                  X R*                  S9$ )z;Pack sequences in a pyarrow Table using a wrapped strategy.r   r:   r   r   )r   r   r   r   r   r   r   r   ChunkedArrayr   r   r   as_pyrW   r   r   r   concatenater   r   r   rn   )r`   r   r   r   r   r   num_elementsr   s           r"   _pack_wrappedr   c  s   G""==  --1L1LV[[1Y1Y&"//22..0$nnfmmVAJ,,.1B1B1DEFv;LLL002Eii<5IGnng~%>?G&\--g>Fv # 88/D/DEEr$   strategy
map_kwargsc                     Uc  0 nU R                  S5      n US:X  a  U R                  " [        4SSU0S.UD6n O2US:X  a  U R                  " [        4SSU0S.UD6n O[	        SU S	35      eU R                  S5      n U $ )
a  
Pack sequences in a dataset into chunks of size `seq_length`.

Args:
    dataset (`Dataset` or `DatasetDict`):
        Dataset to pack
    seq_length (`int`):
        Target sequence length to pack to.
    strategy (`str`, *optional*, defaults to `"bfd"`):
        Packing strategy to use. Can be either:

        - `"bfd"` (Best Fit Decreasing): Slower but preserves sequence boundaries. Sequences are never cut in the
            middle.
        - `"wrapped"`: Faster but more aggressive. Ignores sequence boundaries and will cut sequences in the middle
            to completely fill each packed sequence with data.
    map_kwargs (`dict` or `None`, *optional*, defaults to `None`):
        Additional keyword arguments to pass to the dataset's map method when packing examples.

Returns:
    `Dataset` or `DatasetDict`: The dataset with packed sequences. The number of examples may decrease as sequences
    are combined.

Example:
```python
>>> from datasets import Dataset
>>> from trl import pack_dataset

>>> examples = {
...     "input_ids": [[1, 2, 3], [4, 5], [6, 7, 8], [9]],
...     "attention_mask": [[1, 1, 0], [1, 0], [1, 0, 0], [1]],
... }
>>> dataset = Dataset.from_dict(examples)
>>> packed_dataset = pack_dataset(dataset, seq_length=4, strategy="bfd")
>>> packed_dataset[:]
{'input_ids': [[1, 2, 3, 9], [6, 7, 8], [4, 5]],
'attention_mask': [[1, 1, 0, 1], [1, 0, 0], [1, 0]],
'seq_lengths': [[3, 1], [3], [2]]}
```
NarrowbfdTr   )ri   	fn_kwargswrappedzInvalid packing strategy: z. Use 'bfd' or 'wrapped'.)with_formatrk   r   r   r   )re   r   r   r   s       r"   pack_datasetr   u  s    T 
!!'*G5++ij,PZA[j_ij	Y	++mnTlT^E_ncmn5hZ?XYZZ!!$'GNr$   
max_lengthc                    ^ Uc  0 n[        U [        5      (       a?  U4S jnU R                  S5      n U R                  " U4SS0UD6n U R                  S5      n U $ U4S jnU R                  " U4SS0UD6n U $ )a\  
Truncate sequences in a dataset to a specified `max_length`.

Args:
    dataset (`Dataset` or `DatasetDict`):
        Dataset to truncate.
    max_length (`int`):
        Maximum sequence length to truncate to.
    map_kwargs (`dict` or `None`, *optional*, defaults to `None`):
        Additional keyword arguments to pass to the dataset's map method when truncating examples.

Returns:
    `Dataset` or `DatasetDict`: The dataset with truncated sequences.

Example:
```python
>>> from datasets import Dataset

>>> examples = {
...     "input_ids": [[1, 2, 3], [4, 5, 6, 7], [8]],
...     "attention_mask": [[0, 1, 1], [0, 0, 1, 1], [1]],
... }
>>> dataset = Dataset.from_dict(examples)
>>> truncated_dataset = truncate_dataset(dataset, max_length=2)
>>> truncated_dataset[:]
{'input_ids': [[1, 2], [4, 5], [8]],
 'attention_mask': [[0, 1], [0, 0], [1]]}
```
Nc                   > / nU R                    H  n[        R                  R                  UR                  5      (       d.  [        R                  R                  UR                  5      (       a  [        R                  " UST5      nUR                  U5        M     [        R                  R                  XR                  S9$ )Nr   r   )r   r   r   r   r   r   r   r   r   r   r   r   rn   )r`   truncated_columnsr   r   s      r"   truncate"truncate_dataset.<locals>.truncate  s     ""**==((559T9TU[U`U`9a9a]]61jAF!((0 + 88''(9AVAV'WWr$   r   ri   Tc                    > 0 nU R                  5        H<  u  p#U(       a,  [        US   [        5      (       a  U Vs/ s H  oDS T PM	     nnX1U'   M>     U$ s  snf )Nr   )itemsr   r-   )r`   truncated_examplesr0   r   r   r   s        r"   r   r     s^    !#'~~/jD99:@A&3+:.&FA*03'  0 &% Bs   A)r   r   r   rk   )re   r   r   r   s    `  r"   truncate_datasetr     s    @ 
'7##	X %%g.++hCC
C%%d+  N	& ++

 

 Nr$   c                     U R                  S5      n[        U[        5      (       a'  US   n[        U[        5      (       a  SU;   a  SU;   a  gg)a  
Check if the example is in a conversational format (from/value). Note that this format isn't recommended. Prefer
the ChatML format (role/content)

Args:
    example (`dict[str, Any]`):
        A single data entry of a dataset. The example can have different keys depending on the dataset type.

Returns:
    `bool`:
        `True` if the data is in a conversational Chatformat, `False` otherwise.

Examples:

```python
>>> example = {"conversations": [{"from": "user", "value": "What color is the sky?"}]}
>>> is_conversational_from_value(example)
True

>>> example = {"conversations": [{"role": "user", "content": "What color is the sky?"}]}
>>> is_conversational_from_value(example)
False

>>> example = {"conversations": "The sky is"}
>>> is_conversational_from_value(example)
False
```
conversationsr   fromvalueTF)getr   r-   r.   )r%   r2   r3   s      r"   is_conversational_from_valuer     sK    : [[1N.$''&q)mT**v/F7VcKcr$   c                 @   S H}  nX;   d  M
  [        X   [        5      (       d  M#  X   nU HP  n[        U[        5      (       d  M  SU;   a  UR                  S5      US'   SU;   d  M<  UR                  S5      US'   MR     M     SU ;   a  U R                  S5      U S'   U $ )a  
Convert a conversational dataset with fields `from` and `value` to ChatML format.

This function modifies conversational data to align with OpenAI's ChatML format:
- Replaces the key `"from"` with `"role"` in message dictionaries.
- Replaces the key `"value"` with `"content"` in message dictionaries.
- Renames `"conversations"` to `"messages"` for consistency with ChatML.

Args:
    example (`dict[str, list]`):
        A single data entry containing a list of messages.

Returns:
    `dict[str, list]`:
        Example reformatted to ChatML style.

Example:
```python
>>> from trl import maybe_convert_to_chatml

>>> example = {
...     "conversations": [
...         {"from": "user", "value": "What color is the sky?"},
...         {"from": "assistant", "value": "It is blue."},
...     ]
... }
>>> maybe_convert_to_chatml(example)
{'messages': [{'role': 'user', 'content': 'What color is the sky?'},
              {'role': 'assistant', 'content': 'It is blue.'}]}
```
)r'   r*   r(   r)   r   r   r   r   r   r   r   r   )r   r-   r.   r,   )r%   r0   r   r    s       r"   maybe_convert_to_chatmlr     s    B [>jt<<|H#gt,,(*1++f*=')-4[[-A	* $ [ '!%kk/:
Nr$   r?   )NN)r   N)1collectionsr   r   collections.abcr   	itertoolsr   typingr   r   r	   r
   r   numpyr   r   r   pyarrow.computecomputer   pyarrow.typesdatasetsr   r   transformersr   r   r-   r.   r   r   r#   boolr4   rT   r_   rd   rl   ro   ru   ry   r{   r   r   r   r   r   r   r   r@   r$   r"   <module>r     s}   + $  : :     ) 0 mWk:-x$tCH~*> -xC -xTX -x`&tCH~ &$ &X 48a#tDcN++,a&a DtX~./0a
 
#s(^aN 48;#tDcN++,;&; DtX~./0; 	;
 
#s(^;|$tCd38n)=$=>? DcSWX\]`be]eXfSgNgIhDi  QU(w(w$,SM(w@H(w(wX QU//$,SM/@H//dDh/ Dh4G &ZZ$sDy/ ZZd39o ZZz* *ZAd Adc Adbhh AdHFBHH F# F"(( F& jn55&)5585NVW[\_ad\dWeNf55r SW>>&)>7?S#X7O>>B%$sCx. %T %P/T#t)_ /c4i /r$   