Combines multiple sequences of tokens into a single sequence for BERT. The format is: [CLS] first seq [SEP] second seq [SEP] third_seq [SEP] ... [SEP] If the combined tokens exceed max_seq_len: - We try to keep as much of the first sequence as possible. - If room remains, we try to keep
(input_seqs, max_seq_len, cls_id, sep_id)
| 553 | |
| 554 | |
| 555 | def bert_format(input_seqs, max_seq_len, cls_id, sep_id): |
| 556 | """Combines multiple sequences of tokens into a single sequence for BERT. |
| 557 | |
| 558 | The format is: |
| 559 | [CLS] first seq [SEP] second seq [SEP] third_seq [SEP] ... [SEP] |
| 560 | |
| 561 | If the combined tokens exceed max_seq_len: |
| 562 | - We try to keep as much of the first sequence as possible. |
| 563 | - If room remains, we try to keep as much of the second sequence. |
| 564 | - ... and so on. |
| 565 | - We always make room for all of the [CLS] and [SEP] tokens. |
| 566 | |
| 567 | Args: |
| 568 | input_seqs (list): a list of sequences, where each seq is a list of ints. |
| 569 | max_seq_len (int): max sequence length. |
| 570 | cls_id (int): integer ID for the [CLS] token. |
| 571 | sep_id (int): integer ID for the [SEP] token. |
| 572 | |
| 573 | Returns: |
| 574 | an instance of BertInputs, where each attribute is an int32 |
| 575 | Tensor with shape [max_seq_len]. |
| 576 | """ |
| 577 | # Overall token budget, after reserving space for special tokens. |
| 578 | token_budget = max_seq_len - 1 - len(input_seqs) |
| 579 | if token_budget < 0: |
| 580 | raise ValueError( |
| 581 | 'max_seq_len not large enough to include all special tokens.') |
| 582 | |
| 583 | input_ids = [cls_id] |
| 584 | segment_ids = [0] |
| 585 | input_mask = [1] |
| 586 | |
| 587 | for segment_id, raw_input_seq in enumerate(input_seqs): |
| 588 | # Truncate to stay within the remaining token budget. |
| 589 | input_seq = raw_input_seq[:token_budget] |
| 590 | input_seq_len = len(input_seq) |
| 591 | |
| 592 | input_ids.extend(input_seq) |
| 593 | input_ids.append(sep_id) |
| 594 | |
| 595 | segment_ids.extend([segment_id] * (input_seq_len + 1)) |
| 596 | input_mask.extend([1] * (input_seq_len + 1)) |
| 597 | |
| 598 | # Subtract from budget. |
| 599 | token_budget -= input_seq_len |
| 600 | |
| 601 | assert len(input_ids) == len(input_mask) |
| 602 | assert len(input_ids) == len(segment_ids) |
| 603 | |
| 604 | # Pad with zeroes up to max_seq_len, and convert to TF Tensor. |
| 605 | as_tensor = lambda arr: tf.constant(truncate_or_pad(arr, max_seq_len, 0)) |
| 606 | input_ids = as_tensor(input_ids) |
| 607 | input_mask = as_tensor(input_mask) |
| 608 | segment_ids = as_tensor(segment_ids) |
| 609 | |
| 610 | return BertInputs( |
| 611 | token_ids=input_ids, mask=input_mask, segment_ids=segment_ids) |
| 612 |
no test coverage detected
searching dependent graphs…