Skip to content

Add grobid_custom_hybrid profile with SciELO-preprints reference segmenter - #680

Draft
de-code wants to merge 22 commits into
mainfrom
add-reference-segmenter-scielo-preprints-profile
Draft

Add grobid_custom_hybrid profile with SciELO-preprints reference segmenter#680
de-code wants to merge 22 commits into
mainfrom
add-reference-segmenter-scielo-preprints-profile

Conversation

@de-code

@de-code de-code commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

part of https://github.com/eLifePathways/ScienceBeam2.0/issues/113

Introduces a new sequence-model profile that overlays the grobid 0.9.0 CRF/wapiti baseline with our own retrained DELFT models, starting with a CustomBidLSTM_CRF reference segmenter trained on SciELO preprints. Intended to grow as more custom models are retrained and swapped in.

…enter

Introduces a new sequence-model profile that overlays the grobid 0.9.0 CRF/wapiti baseline with our own retrained DELFT models, starting with a CustomBidLSTM_CRF reference segmenter trained on SciELO preprints.
Intended to grow as more custom models are retrained and swapped in.
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

ScienceBeam Parser Evaluation

Overall (277 docs across 6 corpora)

grobid 0.9.0-crf (default): 277 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 277 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 277 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.564 0.552 0.552 -0.011 +0.000
title (levenshtein) string 0.710 0.713 0.713 +0.003 +0.000
title (edit_sim) string 0.719 0.720 0.720 +0.001 +0.000
abstract (levenshtein) string 0.665 0.665 0.665 +0.000 +0.000
abstract (edit_sim) string 0.697 0.697 0.697 +0.000 +0.000
author_full_names (levenshtein) partial_ulist 0.764 0.755 0.755 -0.008 +0.000
author_full_names (edit_sim) partial_ulist 0.770 0.765 0.765 -0.005 +0.000
affiliation_text (levenshtein) partial_ulist 0.497 0.483 0.483 -0.014 +0.000
affiliation_text (edit_sim) partial_ulist 0.605 0.579 0.579 -0.026 +0.000
keywords (levenshtein) partial_ulist 0.677 0.000 0.000 -0.677 +0.000
keywords (edit_sim) partial_ulist 0.631 0.000 0.000 -0.631 +0.000
body_section_titles (levenshtein) partial_list 0.360 0.357 0.357 -0.002 +0.000
body_section_titles (edit_sim) partial_list 0.350 0.353 0.353 +0.003 +0.000
acknowledgement (levenshtein) string 0.613 0.528 0.528 -0.085 +0.000
acknowledgement (edit_sim) string 0.606 0.528 0.528 -0.077 +0.000
first_reference_text (levenshtein) string 0.523 0.540 0.537 +0.014 -0.002
first_reference_text (edit_sim) string 0.666 0.669 0.675 +0.009 +0.007
reference_title (levenshtein) partial_list 0.494 0.480 0.444 -0.049 -0.035
reference_title (edit_sim) partial_list 0.495 0.492 0.454 -0.042 -0.038
reference_doi (levenshtein) partial_ulist 0.703 0.573 0.119 -0.583 -0.454
reference_doi (edit_sim) partial_ulist 0.649 0.547 0.088 -0.561 -0.459
biorxiv (43 docs)

grobid 0.9.0-crf (default): 43 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 43 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 43 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.911 0.883 0.883 -0.028 +0.000
title (levenshtein) string 0.988 0.988 0.988 +0.000 +0.000
title (edit_sim) string 0.976 0.976 0.976 +0.000 +0.000
abstract (levenshtein) string 0.806 0.806 0.806 +0.000 +0.000
abstract (edit_sim) string 0.787 0.795 0.795 +0.008 +0.000
author_full_names (levenshtein) partial_ulist 0.983 0.981 0.981 -0.002 +0.000
author_full_names (edit_sim) partial_ulist 0.966 0.972 0.972 +0.006 +0.000
affiliation_text (levenshtein) partial_ulist 0.886 0.839 0.839 -0.047 +0.000
affiliation_text (edit_sim) partial_ulist 0.888 0.840 0.840 -0.049 +0.000
keywords (levenshtein) partial_ulist 0.880 0.000 0.000 -0.880 +0.000
keywords (edit_sim) partial_ulist 0.874 0.000 0.000 -0.874 +0.000
body_section_titles (levenshtein) partial_list 0.450 0.364 0.364 -0.086 +0.000
body_section_titles (edit_sim) partial_list 0.429 0.365 0.365 -0.064 +0.000
acknowledgement (levenshtein) string 0.746 0.552 0.552 -0.195 +0.000
acknowledgement (edit_sim) string 0.739 0.575 0.575 -0.163 +0.000
first_reference_text (levenshtein) string 0.925 0.925 0.925 +0.000 +0.000
first_reference_text (edit_sim) string 0.885 0.885 0.875 -0.010 -0.010
reference_title (levenshtein) partial_list 0.720 0.756 0.565 -0.155 -0.191
reference_title (edit_sim) partial_list 0.679 0.717 0.546 -0.133 -0.171
reference_doi (levenshtein) partial_ulist 0.845 0.837 0.023 -0.823 -0.814
reference_doi (edit_sim) partial_ulist 0.814 0.810 0.007 -0.807 -0.804
ore (50 docs)

grobid 0.9.0-crf (default): 50 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 50 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 50 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.551 0.529 0.529 -0.021 +0.000
title (levenshtein) string 0.611 0.630 0.630 +0.019 +0.000
title (edit_sim) string 0.722 0.737 0.737 +0.015 +0.000
abstract (levenshtein) string 0.667 0.667 0.667 +0.000 +0.000
abstract (edit_sim) string 0.721 0.723 0.723 +0.002 +0.000
author_full_names (levenshtein) partial_ulist 0.807 0.801 0.801 -0.005 +0.000
author_full_names (edit_sim) partial_ulist 0.797 0.798 0.798 +0.001 +0.000
affiliation_text (levenshtein) partial_ulist 0.583 0.525 0.525 -0.058 +0.000
affiliation_text (edit_sim) partial_ulist 0.596 0.532 0.532 -0.064 +0.000
keywords (levenshtein) partial_ulist 0.268 0.000 0.000 -0.268 +0.000
keywords (edit_sim) partial_ulist 0.269 0.000 0.000 -0.269 +0.000
body_section_titles (levenshtein) partial_list 0.202 0.231 0.231 +0.029 +0.000
body_section_titles (edit_sim) partial_list 0.237 0.271 0.271 +0.034 +0.000
acknowledgement (levenshtein) string 0.923 0.889 0.889 -0.034 +0.000
acknowledgement (edit_sim) string 0.937 0.885 0.885 -0.052 +0.000
first_reference_text (levenshtein) string 0.485 0.485 0.485 +0.000 +0.000
first_reference_text (edit_sim) string 0.636 0.622 0.623 -0.013 +0.000
reference_title (levenshtein) partial_list 0.246 0.310 0.315 +0.069 +0.004
reference_title (edit_sim) partial_list 0.278 0.336 0.335 +0.057 -0.000
reference_doi (levenshtein) partial_ulist 0.661 0.032 0.028 -0.632 -0.004
reference_doi (edit_sim) partial_ulist 0.522 0.010 0.007 -0.516 -0.003
pkp (50 docs)

grobid 0.9.0-crf (default): 50 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 50 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 50 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.667 0.649 0.649 -0.018 +0.000
title (levenshtein) string 0.780 0.780 0.780 +0.000 +0.000
title (edit_sim) string 0.740 0.740 0.740 +0.000 +0.000
abstract (levenshtein) string 0.880 0.880 0.880 +0.000 +0.000
abstract (edit_sim) string 0.848 0.848 0.848 +0.001 +0.000
author_full_names (levenshtein) partial_ulist 0.842 0.840 0.840 -0.002 +0.000
author_full_names (edit_sim) partial_ulist 0.829 0.828 0.828 -0.002 +0.000
affiliation_text (levenshtein) partial_ulist 0.703 0.675 0.675 -0.029 +0.000
affiliation_text (edit_sim) partial_ulist 0.765 0.705 0.705 -0.059 +0.000
keywords (levenshtein) partial_ulist 0.953 0.000 0.000 -0.953 +0.000
keywords (edit_sim) partial_ulist 0.945 0.000 0.000 -0.945 +0.000
body_section_titles (levenshtein) partial_list 0.598 0.649 0.649 +0.051 +0.000
body_section_titles (edit_sim) partial_list 0.542 0.588 0.588 +0.045 +0.000
acknowledgement (levenshtein) string 0.783 0.600 0.600 -0.183 +0.000
acknowledgement (edit_sim) string 0.737 0.588 0.588 -0.149 +0.000
first_reference_text (levenshtein) string 0.947 0.947 0.958 +0.011 +0.011
first_reference_text (edit_sim) string 0.911 0.911 0.942 +0.031 +0.031
reference_title (levenshtein) partial_list 0.790 0.748 0.676 -0.114 -0.072
reference_title (edit_sim) partial_list 0.772 0.736 0.667 -0.105 -0.069
reference_doi (levenshtein) partial_ulist 0.891 0.889 0.387 -0.504 -0.502
reference_doi (edit_sim) partial_ulist 0.855 0.889 0.373 -0.482 -0.516
scielo_br (50 docs)

grobid 0.9.0-crf (default): 50 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 50 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 50 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.551 0.551 0.551 +0.000 +0.000
title (levenshtein) string 0.684 0.684 0.684 +0.000 +0.000
title (edit_sim) string 0.698 0.698 0.698 +0.000 +0.000
abstract (levenshtein) string 0.718 0.718 0.718 +0.000 +0.000
abstract (edit_sim) string 0.699 0.696 0.696 -0.004 +0.000
author_full_names (levenshtein) partial_ulist 0.766 0.736 0.736 -0.030 +0.000
author_full_names (edit_sim) partial_ulist 0.777 0.752 0.752 -0.025 +0.000
affiliation_text (levenshtein) partial_ulist 0.000 0.000 0.000 +0.000 +0.000
affiliation_text (edit_sim) partial_ulist 0.339 0.326 0.326 -0.013 +0.000
keywords (levenshtein) partial_ulist 0.620 0.000 0.000 -0.620 +0.000
keywords (edit_sim) partial_ulist 0.588 0.000 0.000 -0.588 +0.000
body_section_titles (levenshtein) partial_list 0.418 0.411 0.411 -0.006 +0.000
body_section_titles (edit_sim) partial_list 0.424 0.419 0.419 -0.005 +0.000
acknowledgement (levenshtein) string 0.762 0.762 0.762 +0.000 +0.000
acknowledgement (edit_sim) string 0.761 0.761 0.761 +0.000 +0.000
first_reference_text (levenshtein) string 0.000 0.039 0.039 +0.039 +0.000
first_reference_text (edit_sim) string 0.429 0.436 0.454 +0.025 +0.019
reference_title (levenshtein) partial_list 0.572 0.503 0.545 -0.026 +0.043
reference_title (edit_sim) partial_list 0.555 0.510 0.536 -0.018 +0.026
reference_doi (levenshtein) partial_ulist 0.942 0.880 0.162 -0.781 -0.719
reference_doi (edit_sim) partial_ulist 0.926 0.827 0.071 -0.855 -0.757
scielo_mx (34 docs)

grobid 0.9.0-crf (default): 34 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 34 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 34 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.162 0.162 0.162 +0.000 +0.000
title (levenshtein) string 0.583 0.583 0.583 +0.000 +0.000
title (edit_sim) string 0.604 0.591 0.591 -0.013 +0.000
abstract (levenshtein) string 0.111 0.111 0.111 +0.000 +0.000
abstract (edit_sim) string 0.474 0.461 0.461 -0.013 +0.000
author_full_names (levenshtein) partial_ulist 0.678 0.682 0.682 +0.004 +0.000
author_full_names (edit_sim) partial_ulist 0.695 0.694 0.694 -0.001 +0.000
affiliation_text (levenshtein) partial_ulist 0.102 0.098 0.098 -0.003 +0.000
affiliation_text (edit_sim) partial_ulist 0.311 0.313 0.313 +0.002 +0.000
keywords (levenshtein) partial_ulist 0.718 0.000 0.000 -0.718 +0.000
keywords (edit_sim) partial_ulist 0.616 0.000 0.000 -0.616 +0.000
body_section_titles (levenshtein) partial_list 0.000 0.000 0.000 +0.000 +0.000
body_section_titles (edit_sim) partial_list 0.000 0.000 0.000 +0.000 +0.000
acknowledgement (levenshtein) string 0.000 0.000 0.000 +0.000 +0.000
acknowledgement (edit_sim) string 0.000 0.000 0.000 +0.000 +0.000
first_reference_text (levenshtein) string 0.419 0.419 0.419 +0.000 +0.000
first_reference_text (edit_sim) string 0.465 0.452 0.447 -0.018 -0.005
reference_title (levenshtein) partial_list 0.301 0.239 0.145 -0.156 -0.095
reference_title (edit_sim) partial_list 0.326 0.283 0.210 -0.116 -0.073
reference_doi (levenshtein) partial_ulist 0.000 0.000 0.000 +0.000 +0.000
reference_doi (edit_sim) partial_ulist 0.000 0.000 0.000 +0.000 +0.000
scielo_preprints-jats (50 docs)

grobid 0.9.0-crf (default): 50 docs | sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf): 50 docs | sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid): 50 docs

Field (method) Type grobid 0.9.0-crf (default) sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf) sciencebeam-parser:pr-680-5716df43-20260817.1120 (grobid_custom_hybrid) Δ grobid 0.9.0-crf (default) Δ sciencebeam-parser:main-d0f4519b-20260817.1058 (grobid_crf)
title (exact) string 0.462 0.462 0.462 +0.000 +0.000
title (levenshtein) string 0.611 0.611 0.611 +0.000 +0.000
title (edit_sim) string 0.571 0.572 0.572 +0.001 +0.000
abstract (levenshtein) string 0.649 0.649 0.649 +0.000 +0.000
abstract (edit_sim) string 0.595 0.600 0.600 +0.004 +0.000
author_full_names (levenshtein) partial_ulist 0.509 0.499 0.499 -0.010 +0.000
author_full_names (edit_sim) partial_ulist 0.557 0.553 0.553 -0.004 +0.000
affiliation_text (levenshtein) partial_ulist 0.636 0.686 0.686 +0.051 +0.000
affiliation_text (edit_sim) partial_ulist 0.677 0.712 0.712 +0.035 +0.000
keywords (levenshtein) partial_ulist 0.662 0.000 0.000 -0.662 +0.000
keywords (edit_sim) partial_ulist 0.522 0.000 0.000 -0.522 +0.000
body_section_titles (levenshtein) partial_list 0.388 0.375 0.375 -0.013 +0.000
body_section_titles (edit_sim) partial_list 0.367 0.361 0.361 -0.006 +0.000
acknowledgement (levenshtein) string 0.286 0.200 0.200 -0.086 +0.000
acknowledgement (edit_sim) string 0.286 0.200 0.200 -0.086 +0.000
first_reference_text (levenshtein) string 0.387 0.438 0.413 +0.026 -0.025
first_reference_text (edit_sim) string 0.635 0.667 0.665 +0.030 -0.001
reference_title (levenshtein) partial_list 0.304 0.283 0.342 +0.038 +0.058
reference_title (edit_sim) partial_list 0.333 0.331 0.362 +0.029 +0.031
reference_doi (levenshtein) partial_ulist 0.671 0.654 0.065 -0.606 -0.589
reference_doi (edit_sim) partial_ulist 0.592 0.606 0.032 -0.560 -0.575

…enter

  Introduces a new sequence-model profile that overlays the grobid 0.9.0
  CRF/wapiti baseline with our own retrained DELFT models, starting with
  a CustomBidLSTM_CRF reference segmenter trained on SciELO preprints.
  Intended to grow as more custom models are retrained and swapped in.
  Also wires up the profile:grobid_custom_hybrid PR label in the
  benchmark workflow so it selects this profile.
de-code added 2 commits July 1, 2026 18:14
Replaces the hardcoded per-profile contains() checks with a step that
extracts any profile:<name> label directly, validated against a safe
character set, so new profiles no longer require a benchmark.yml edit.
Authenticate CI to GCP via Workload Identity Federation so the
grobid_custom_hybrid profile can pull the reference-segmenter model
from gs://sciencebeam-v2-models while the trained model's release is
not yet public.
de-code added 2 commits July 2, 2026 09:03
TensorFlow's built-in gs:// filesystem support only recognizes plain
service-account JSON keys, not the Workload Identity Federation
external_account credential files google-github-actions/auth
produces - those reference a credential source that can't be resolved
from inside the sciencebeam-parser container, causing anonymous
(unauthenticated) requests. Decode a service account key from the
GCS_MODEL_READER_SA_KEY_B64 secret instead and mount it into the
container.
Points the citation model at the new CustomBidLSTM_CRF model in the
private sciencebeam-v2-models GCS bucket, replacing the grobid 0.9.0
wapiti model, while its release is not yet public.
@de-code

de-code commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

This doesn't look that good unfortunately

de-code added 2 commits July 3, 2026 12:23
Custom hybrid profiles are expected to grow beyond this one, so  inherit from a base profile via a code-resolved `extends` key rather  than a YAML anchor - it deep-merges instead of replacing whole model  entries, gives clear errors for unknown/circular references, and  keeps working if profiles ever get split across files.
…file

One conflict, in .github/workflows/benchmark.yml. This branch had already
replaced the job-level BENCHMARK_PROFILE env expression with the "Resolve
benchmark profile" step, which accepts any profile: label and validates it;
main meanwhile added BENCHMARK_CORPORA for the opt-in PLOS corpus. The
resolution keeps the step and drops main's BENCHMARK_PROFILE expression,
which the step supersedes, and takes BENCHMARK_CORPORA unchanged.
…file

One conflict again, in .github/workflows/benchmark.yml, the same one as the
previous merge: main still carries the job-level BENCHMARK_PROFILE
expression that this branch replaced with the "Resolve benchmark profile"
step, so the resolution drops it once more. #691 also rewrote the comment
above BENCHMARK_CORPORA, whose body had already auto-merged with the new
github.ref == 'refs/heads/main' condition, so that comment is taken from
main.
The step wrote BENCHMARK_PROFILE to the environment and said nothing, so
which profile a run used could only be inferred later, from the parser
invocation further down the log. It now reports the profile and where it
came from - label, workflow_dispatch input, or the default. A notice rather
than a plain echo, so it also surfaces at the top of the run.
The labels expression renders as null on push and workflow_dispatch, where
there is no pull request, and plain .[] treats iterating that as an error.
It was masked: jq's failure sits mid-pipeline, so head's success is what the
assignment saw, and the empty result fell through to the default. The log
still carried an error line on every main run, and setting shell: bash would
have added pipefail and turned it into a failed step - on exactly the runs
that produce the recorded baseline. .[]? yields nothing instead.
@de-code

de-code commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

Still showing a regression with those retrained models. That indicates issues with the training data (or how it is being combined)

The visited profiles were carried as a frozenset, so the chain the error
advertises printed in arbitrary order - and only across processes, since
within one it is stable, which is how it passed a test suite. A tuple keeps
the order, and the new test pins it.

Matches the standalone extends branch exactly, so config.py does not conflict
when this branch next merges main.
…file

Three conflicts, each from this branch having a fuller version of what main
just gained.

benchmark.yml: main's profile-resolution step arrived where this branch
already has the GCS key step in front of it, so the resolution keeps both,
GCS first.

config.yml: main's grobid_custom_hybrid states only `extends`, this branch
overrides citation and reference_segmenter on top of it, so the overrides
stay.

config_test.py takes main's DEFAULT_CONFIG_FILE import, and its assertion is
rewritten. It asserted the hybrid resolves to exactly what grobid_crf
resolves to, which is true on main and false here - which is what it was
written to catch. It now names what this branch actually intends: the same
ten models, differing in citation and reference_segmenter alone.
It named which models the profile overrides, so a config change had to come
with a test change - and it was the config, not any behaviour, that the
assertion described. That extends inherits the base and lets a profile
override one model is already covered by profile_b_extended in
MINIMAL_PROFILE_CONFIG, on a fixture that no model swap disturbs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant