Skip to content

Conversation

@charanw
Copy link

@charanw charanw commented Dec 10, 2025

Contributor: Charan Williams (charanw2@illinois.edu)

Contribution Type: New Model

Description:
Added a new clinical summarization model, BHCToAVS, which converts Brief Hospital Course (BHC) notes into patient-friendly After-Visit Summaries (AVS). The model wraps a fine-tuned Mistral-7B LoRA adapter hosted on Hugging Face and integrates with the PyHealth model API. This contribution includes the full model implementation, unit tests, documentation, and an example usage script.

Files to Review:

  • pyhealth/models/bhc_to_avs.py — Main model implementation
  • pyhealth/models/__init__.py — Added import for the new model
  • tests/core/test_bhc_to_avs.py — Unit test for the BHCToAVS model
  • docs/api/models/pyhealth.models.bhc_to_avs.rst — Sphinx documentation file
  • docs/api/models.rst — Updated model index to include BHCToAVS
  • examples/bhc_to_avs_example.py — Example usage demonstrating model prediction

Introduces the BHCToAVS model, which converts clinical Brief Hospital Course (BHC) notes into After-Visit Summaries (AVS) using a fine-tuned Mistral 7B model with LoRA adapters. Adds model implementation, documentation, an example usage script, and unit tests.
@Logiquo Logiquo added the component: model Contribute a new model to PyHealth label Dec 18, 2025
@Logiquo Logiquo requested a review from Copilot December 27, 2025 10:24
@Logiquo Logiquo self-requested a review December 27, 2025 10:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new clinical summarization model, BHCToAVS, that converts Brief Hospital Course (BHC) notes into patient-friendly After-Visit Summaries (AVS) using a fine-tuned Mistral-7B LoRA adapter. The implementation integrates with PyHealth's model API and includes comprehensive documentation and examples.

  • Implements a new text generation model wrapping a Hugging Face LoRA adapter
  • Adds unit tests with graceful handling of model download failures
  • Provides example usage demonstrating the model's clinical text summarization capabilities

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pyhealth/models/bhc_to_avs.py Core model implementation with predict() method for generating patient-friendly summaries
pyhealth/models/init.py Added BHCToAVS to module exports
tests/core/test_bhc_to_avs.py Unit test validating the predict method with error handling for gated models
docs/api/models/pyhealth.models.BHCToAVS.rst Sphinx autodoc configuration for the new model
docs/api/models.rst Updated model index to include BHCToAVS
examples/bhc_to_avs_example.py Example script demonstrating model usage with synthetic clinical text

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Logiquo
Copy link
Collaborator

Logiquo commented Dec 27, 2025

The CI has failed.

@Logiquo Logiquo added the status: wait response Pending PR author's response label Dec 27, 2025
charanw and others added 2 commits December 29, 2025 11:18
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Logiquo Logiquo added status: need review Pending maintainer's review and removed status: wait response Pending PR author's response labels Dec 29, 2025
charanw and others added 6 commits December 29, 2025 11:21
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Enhanced the BHCToAVS model with improved docstrings, error handling for Hugging Face token requirements, and more robust pipeline initialization. Updated and expanded the test suite to include both unit tests with a mocked pipeline and an optional integration test for real model inference.
Introduces a __post_init__ method in BHCToAVS to call the BaseModel initializer, ensuring proper nn.Module setup. Also updates docstring formatting and attribute documentation for clarity.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +86 to +92
raise RuntimeError(
"Hugging Face token not found. This model requires access to a gated repository.\n\n"
"Set the HF_TOKEN environment variable or pass hf_token=... when initializing BHCToAVS.\n\n"
"Example:\n"
" export HF_TOKEN='hf_...'\n"
" model = BHCToAVS()\n"
)
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message spans lines 87-92 and provides good guidance, but the message could be more specific about where to obtain a HuggingFace token. Consider adding a link to the HuggingFace token generation page (https://huggingface.co/settings/tokens) to help users quickly resolve this issue.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +41
# Prompt used during fine-tuning
_PROMPT = (
"Summarize for the patient what happened during the hospital stay based on this doctor's note:\n"
"{bhc}\n\n"
"Summary for the patient:\n"
)
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 36 states "Prompt used during fine-tuning" but this prompt is actually used during inference (as seen on line 146). If this prompt was indeed used during fine-tuning and is also being reused during inference, the comment should clarify this. If it's only used during inference, the comment is misleading and should be corrected to "Prompt template used during inference" or similar.

Copilot uses AI. Check for mistakes.
Comment on lines +78 to +120
def _get_pipeline(self):
"""Create and cache the text-generation pipeline."""
if not hasattr(self, "_pipeline"):
# Resolve HuggingFace token
token = self._resolve_token()

# Throw RuntimeError if token is not found
if token is None:
raise RuntimeError(
"Hugging Face token not found. This model requires access to a gated repository.\n\n"
"Set the HF_TOKEN environment variable or pass hf_token=... when initializing BHCToAVS.\n\n"
"Example:\n"
" export HF_TOKEN='hf_...'\n"
" model = BHCToAVS()\n"
)

# Load base model
base = AutoModelForCausalLM.from_pretrained(
self.base_model_id,
torch_dtype=torch.bfloat16,
device_map="auto",
token=token,
)

# Load LoRA adapter
model = PeftModelForCausalLM.from_pretrained(
base,
self.adapter_model_id,
torch_dtype=torch.bfloat16,
token=token,
)

tokenizer = AutoTokenizer.from_pretrained(self.base_model_id, token=token)

# Create HF pipeline
self._pipeline = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
model_kwargs={"torch_dtype": torch.bfloat16},
)

return self._pipeline
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _get_pipeline method loads a large 7B parameter model without any explicit guidance on resource requirements or expected load time. Consider adding documentation (either in the class docstring or method docstring) about: (1) expected memory requirements (GPU/CPU), (2) approximate model loading time, and (3) recommended hardware specifications. This would help users understand the resource implications before attempting to use the model.

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +74
def __post_init__(self):
# Ensure nn.Module (via BaseModel) is initialized
super().__init__()

Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BHCToAVS class uses a dataclass decorator but also inherits from BaseModel (which is an nn.Module). The post_init method calls super().init(), but this pattern is inconsistent with how BaseModel is typically used in the codebase. Looking at SdohClassifier (another dataclass-based model in the same codebase), it does not override post_init. Additionally, BaseModel's init expects an optional dataset parameter, but this implementation calls it without any arguments. This could lead to incorrect initialization. Consider removing post_init entirely or ensuring it properly initializes the BaseModel with appropriate parameters.

Suggested change
def __post_init__(self):
# Ensure nn.Module (via BaseModel) is initialized
super().__init__()

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +69
base_model_id: str = field(default="mistralai/Mistral-7B-Instruct-v0.3")
adapter_model_id: str = field(default="williach31/mistral-7b-bhc-to-avs-lora")
hf_token: str | None = None
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BHCToAVS model deviates from the standard PyHealth model API pattern. Most models in the codebase (e.g., LogisticRegression, AdaCare, GAMENet) accept a dataset parameter in their initialization to query information like tokens and schemas. This model does not accept or use a dataset parameter, which is inconsistent with the BaseModel interface it inherits from. Consider whether this model should follow the standard pattern or if the deviation is intentional for this use case. If intentional, this should be clearly documented.

Copilot uses AI. Check for mistakes.
self.assertGreater(len(summary.strip()), 0)

# Output should be different from input
self.assertNotIn(bhc_text[:40], summary)
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test assertion on line 66 uses a weak check that only verifies the first 40 characters of the input are not present in the output. This could pass even if the model is simply copying most of the input text or behaving incorrectly. Consider adding more robust assertions that verify the output actually represents a simplified, patient-friendly summary (e.g., checking for absence of medical jargon, checking for specific expected transformations, or verifying the output differs meaningfully from the input).

Copilot uses AI. Check for mistakes.
charanw and others added 3 commits December 29, 2025 13:03
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@charanw
Copy link
Author

charanw commented Dec 29, 2025

Thank you for the review. I updated the tests by adding a separate optional integration test and modifying the unit test to patch in a dummy pipeline, so CI does not require model downloads or gated access.

@Logiquo
Copy link
Collaborator

Logiquo commented Dec 30, 2025

Typically a BaseModels should take a SampleDataset to examine a first few batch of data to determine how to construct a models. I don't think your model follows this structure?

@Logiquo Logiquo added status: wait response Pending PR author's response and removed status: need review Pending maintainer's review labels Dec 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: model Contribute a new model to PyHealth status: wait response Pending PR author's response

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants