o
    iG                     @   s   d dl Z d dlZd dlZ				 		 dddZ	 				ddd	Z	 				dd
dZdd Zg dZg dZ	d e
de
dd ddddddd d d d d d fddZdS )    N   Finputoutputc
                    sl  |dkrt d| t |k rt dt  d| dg }
d}	  | \}}t|| | d d }|	dkrEt|| |	 d d n
ttdd	 || }tt|| t|| }t|t|d
|  }tt || } || }|r}|  t||k r|t||  } fddtj	d||D }|r|  |
| |
| |t kr	 |
S |}q#)a  Make batch set from json dictionary

    :param Dict[str, Dict[str, Any]] sorted_data: dictionary loaded from data.json
    :param int batch_size: batch size
    :param int max_length_in: maximum length of input to decide adaptive batch size
    :param int max_length_out: maximum length of output to decide adaptive batch size
    :param int min_batch_size: mininum batch size (for multi-gpu)
    :param bool shortest_first: Sort from batch with shortest samples
        to longest if true, otherwise reverse
    :param str ikey: key to access input
        (for ASR ikey="input", for TTS, MT ikey="output".)
    :param int iaxis: dimension to access input
        (for ASR, TTS iaxis=0, for MT iaxis="1".)
    :param str okey: key to access output
        (for ASR, MT okey="output". for TTS okey="input".)
    :param int oaxis: dimension to access output
        (for ASR, TTS, MT oaxis=0, reserved for future research, -1 means all axis.)
    :return: List[List[Tuple[str, dict]]] list of batches
    r   zInvalid batch_size=z#utts(z) is less than min_batch_size(z).Tshapec                 S   s   t | d d S )Nr   r   int)x r	   Q/home/ubuntu/.local/lib/python3.10/site-packages/espnet/utils/training/batchfy.py<lambda>8   s    z batchfy_by_seq.<locals>.<lambda>r   c                       g | ]} | qS r	   r	   .0isorted_datar	   r
   
<listcomp>H       z"batchfy_by_seq.<locals>.<listcomp>)
ValueErrorlenr   maxmapminreversenprandomrandintextendappend)r   
batch_sizemax_length_inmax_length_outmin_batch_sizeshortest_firstikeyiaxisokeyoaxisminibatchesstart_infoilenolenfactorbsend	minibatchmodadditional_minibatchr	   r   r
   batchfy_by_seq   sF   


r4   c                 C   s  |dkrt d| t| }t| d d | d d d }t| d d | d d d }	tdtt|   g }
d}d}	 d}d}d}||k r|| |k rt| ||  d | d d d | }t| ||  d | d d d |	 }||kr|}|| |d  }||kr|d7 }n|dkrt d| d||k r|| |k sQt||t|| }| || }|r|  |
	| d	}t|
| |k r|t|
|  }| t|
kr|
|d  
|
|  |
dd
 }
n)|
| 
|
|d  d
|  |
|d  |d
 |
|d < |d8 }t|
| |k s||krn|}|d7 }qA|dkr.|
d
| }
dd |
D }ttt|
d tt| d tt| d d ttt| d  |
S )a  Make variably sized batch set, which maximizes

    the number of bins up to `batch_bins`.

    :param Dict[str, Dict[str, Any]] sorted_data: dictionary loaded from data.json
    :param int batch_bins: Maximum frames of a batch
    :param int num_batches: # number of batches to use (for debug)
    :param int min_batch_size: minimum batch size (for multi-gpu)
    :param int test: Return only every `test` batches
    :param bool shortest_first: Sort from batch with shortest samples
        to longest if true, otherwise reverse

    :param str ikey: key to access input (for ASR ikey="input", for TTS ikey="output".)
    :param str okey: key to access output (for ASR okey="output". for TTS okey="input".)

    :return: List[Tuple[str, Dict[str, List[Dict[str, Any]]]] list of batches
    r   zinvalid batch_bins=r   r   # utts: Tz$Can't fit one sample in batch_bins (): Please increase the valueNc                 S      g | ]}t |qS r	   r   r   r   r	   r	   r
   r          z"batchfy_by_bin.<locals>.<listcomp> batches containing from  to z	 samples (avg 
 samples).)r   r   r   loggingr+   strr   r   r   r   r   r   mean)r   
batch_binsnum_batchesr"   r#   r$   r&   lengthidimodimr(   r)   nb	next_sizemax_olenr,   r-   r0   batchr   missinglengthsr	   r	   r
   batchfy_by_binX   s     ((





'


rO   c	                 C   s  |dkr|dkr|dkrt dt| }	g }
d}d}||	kr7d}d}d}|| |	k rt| ||  d | d d d }||krM|dkrMt d| dt| ||  d | d d d }||kro|dkrot d| d|| |kr|dkrt d| dt||}t||}||d  |kp|dk}||d  |kp|dk}|| |d  |kp|dk}|r|r|r|d7 }nn|| |	k s+t|	|| }| || }|r|  |
| d}t|
| |k r1|t|
|  }| t|
kr|
|d  |
|  |
dd	 }
n)|
| |
|d  d	|  |
|d  |d	 |
|d < |d8 }t|
| |k s|}||	ks|dkrB|
d	| }
d
d |
D }t	t
t|
d t
t| d t
t| d d t
tt| d  |
S )a  Make variable batch set, which maximizes the number of frames to max_batch_frame.

    :param Dict[str, Dict[str, Any]] sorteddata: dictionary loaded from data.json
    :param int max_frames_in: Maximum input frames of a batch
    :param int max_frames_out: Maximum output frames of a batch
    :param int max_frames_inout: Maximum input+output frames of a batch
    :param int num_batches: # number of batches to use (for debug)
    :param int min_batch_size: minimum batch size (for multi-gpu)
    :param int test: Return only every `test` batches
    :param bool shortest_first: Sort from batch with shortest samples
        to longest if true, otherwise reverse

    :param str ikey: key to access input (for ASR ikey="input", for TTS ikey="output".)
    :param str okey: key to access output (for ASR okey="output". for TTS okey="input".)

    :return: List[Tuple[str, Dict[str, List[Dict[str, Any]]]] list of batches
    r   zbAt least, one of `--batch-frames-in`, `--batch-frames-out` or `--batch-frames-inout` should be > 0r   r   z+Can't fit one sample in --batch-frames-in (r6   z,Can't fit one sample in --batch-frames-out (r7   Nc                 S   r8   r	   r9   r:   r	   r	   r
   r     r;   z$batchfy_by_frame.<locals>.<listcomp>r<   r=   z samplesr>   r?   )r   r   r   r   r   r   r   r   r@   r+   rA   r   rB   )r   max_frames_inmax_frames_outmax_frames_inoutrD   r"   r#   r$   r&   rE   r(   r)   r0   rI   rK   max_ilenr,   r-   in_okout_okinout_okrL   r   rM   rN   r	   r	   r
   batchfy_by_frame   s   
$
$







6


rW   c                    s  dd l }td ||  t|   tdtt   g }d}	 tt || } || }	|r:|	  t|	|k rb|t|	|  }
 fddt	j 
d||
D }|r]|  |	| ||	 |t krnn|}q%|dkr|d | }tdtt|  |S )Nr   zuse shuffled batch.r5   Tc                    r   r	   r	   r   r   r	   r
   r   1  r   z#batchfy_shuffle.<locals>.<listcomp># minibatches: )r   r@   r+   sampleitemsr   rA   r   r   r   r   r   r   )datar   r"   rD   r#   r   r(   r)   r0   r1   r2   r3   r	   r   r
   batchfy_shuffle   s8   



r\   )autoseqbinframe)r   r   shuffleinfr]   c                    sj  |
t vrtd|
 dt  tvrtd dt d |r2d}d}dkr+dn"dkr1dn|	rId}d}dd |dksBJ |dksHJ nd}d}|
dkr}|dkrXd	}
n|dkr_d
}
n|dksk|dksk|dkrnd}
ntdt  td|
  |
d	krdkrtdi }|  D ]\}}|||di |< qg }| D ]d}dkrt	|||||}|
| qt|  fdd| d}tdtt|  |
d	krt||||||||||d
}|
d
krt||||||d}|
dkrt||||||||d}|
| qt|dkr|d }nttj| }|dkr(|d| }tdtt|  |S )a  Make batch set from json dictionary

    if utts have "category" value,

        >>> data = {'utt1': {'category': 'A', 'input': ...},
        ...         'utt2': {'category': 'B', 'input': ...},
        ...         'utt3': {'category': 'B', 'input': ...},
        ...         'utt4': {'category': 'A', 'input': ...}}
        >>> make_batchset(data, batchsize=2, ...)
        [[('utt1', ...), ('utt4', ...)], [('utt2', ...), ('utt3': ...)]]

    Note that if any utts doesn't have "category",
    perform as same as batchfy_by_{count}

    :param Dict[str, Dict[str, Any]] data: dictionary loaded from data.json
    :param int batch_size: maximum number of sequences in a minibatch.
    :param int batch_bins: maximum number of bins (frames x dim) in a minibatch.
    :param int batch_frames_in:  maximum number of input frames in a minibatch.
    :param int batch_frames_out: maximum number of output frames in a minibatch.
    :param int batch_frames_out: maximum number of input+output frames in a minibatch.
    :param str count: strategy to count maximum size of batch.
        For choices, see espnet.asr.batchfy.BATCH_COUNT_CHOICES

    :param int max_length_in: maximum length of input to decide adaptive batch size
    :param int max_length_out: maximum length of output to decide adaptive batch size
    :param int num_batches: # number of batches to use (for debug)
    :param int min_batch_size: minimum batch size (for multi-gpu)
    :param bool shortest_first: Sort from batch with shortest samples
        to longest if true, otherwise reverse
    :param str batch_sort_key: how to sort data before creating minibatches
        ["input", "output", "shuffle"]
    :param bool swap_io: if True, use "input" as output and "output"
        as input in `data` dict
    :param bool mt: if True, use 0-axis of "output" as output and 1-axis of "output"
        as input in `data` dict
    :param int iaxis: dimension to access input
        (for ASR, TTS iaxis=0, for MT iaxis="1".)
    :param int oaxis: dimension to access output (for ASR, TTS, MT oaxis=0,
        reserved for future research, -1 means all axis.)
    :return: List[List[Tuple[str, dict]]] list of batches
    zarg 'count' (z) should be one of zarg 'batch_sort_key' (r   r   r   r   r]   r^   r_   r`   z*cannot detect `count` manually set one of zcount is auto detected as ra   z;batch_sort_key=shuffle is only available if batch_count=seqcategoryc                    s   t | d    d d S )Nr   r   r   r   )r[   batch_sort_axisbatch_sort_keyr	   r
   r     s    zmake_batchset.<locals>.<lambda>)keyr   r5   )	r   r    r!   r"   r#   r$   r%   r&   r'   )rC   r"   r#   r$   r&   )rP   rQ   rR   r"   r#   r$   r&   NrX   )BATCH_COUNT_CHOICESr   BATCH_SORT_KEY_CHOICESr@   r+   rZ   
setdefaultgetvaluesr\   r   sortedrA   r   r4   rO   rW   list	itertoolschain)r[   r   r    r!   rD   r"   r#   rf   swap_iomtcountrC   batch_frames_inbatch_frames_outbatch_frames_inoutr%   r'   r$   r&   category2datakvbatches_listdbatchesr   r	   rd   r
   make_batchsetG  s   >





r}   )r   Fr   r   r   r   )r   r   Fr   r   )ro   r@   numpyr   r4   rO   rW   r\   rh   ri   floatr}   r	   r	   r	   r
   <module>   sT    
T
`
m#