Views
No views yet
Qwen/Qwen2.5-14B-Instruct model, specifically adapted for Named Entity Recognition (NER) in scientific texts. The model has been instruction-tuned to extract specific entity types, outputting them in a structured JSON format.Qwen/Qwen2.5-14B-Instructner_train.json and potentially ner_train_1.json), which consists of scientific text annotated with specific NER labels. The data was transformed into an instruction-response format suitable for instruction-tuning large language models.r=64, lora_alpha=16, lora_dropout=0.1.per_device_train_batch_size: 4gradient_accumulation_steps: 8learning_rate: 2e-4max_steps: 500 (adjust if you used a different number)optim: paged_adamw_8bitfp16: Truegradient_checkpointing: Truetransformers library.1import torch
2from transformers import AutoTokenizer, AutoModelForCausalLM
3from peft import PeftModel
4
5# --- Configuration ---
6# Replace 'YOUR_HF_USERNAME' with your Hugging Face username or organization
7MODEL_REPO_ID = "MikeACedric/finetuned-qwen-for-ner-v2" # Adjust this if you chose a different repo name
8GENERATION_MAX_NEW_TOKENS = 1024 # Max tokens for the JSON output
9
10# Define the NER labels used during training
11NER_LABELS = [
12 "Ecosystem", "Focalpoint", "Locationofstudy", "Mainhypothesisandcorrespondingresults",
13 "Method", "Reccomendationsandsuggestions", "Researchquestions", "Timeperiodofstudy"
14]
15
16# --- Prompts (must match training prompts exactly) ---
17SYSTEM_PROMPT = "You are an expert in scientific reasoning and information extraction."
18USER_CONTEXT_TEMPLATE = """## Task Description
19Perform step-by-step reasoning to identify Named Entities in the scientific text.
20
21Each JSON key must be a single, exact substring from the input text. Each JSON value must be exactly one of these eight labels (no spelling variants):
22
231. "Ecosystem": Refers to the type of natural or artificial environment, land use, or specific study site characteristics beyond just coordinates/city.
242. "Focalpoint": Refers to the main species, organism, or subject of study.
253. "Locationofstudy": Refers to information about the physical setting, coordinates, geographical location, and name of country/city.
264. "Mainhypothesisandcorrespondingresults": Refers to the primary hypothesis tested in the study and its direct, corresponding findings.
275. "Method": Refers to method/technique/instrument used in the study.
286. "Reccomendationsandsuggestions": Refers to proposals for future actions, research, or applications based on the study's findings.
297. "Researchquestions": Refers to the specific problems, gaps, or questions the research aims to address.
308. "Timeperiodofstudy": Refers to information about the timing of the study, including beginning and end date, total duration, timing, and duration of fieldwork. Usually found in the Abstract/Introduction/Methods sections.
31
32- If the text contains multiple distinct phrases all belonging to the same label (for example, four different entities under “Focalpoint”), you must emit each phrase as its own JSON key.
33- Never group more than one phrase under a single key.
34- The output must be a single, flat JSON dictionary. No lists or nested objects.
35- Do not output any extra text, no commentary, no markdown—just the JSON.
36- Ensure all keys are exact, verbatim substrings from the input text. Do not paraphrase or alter the text.
37
38### Input
39{text}
40
41### Output
42Produce ONLY the JSON dictionary. Do NOT include any other text, explanations, or markdown. Start the JSON directly and end it immediately after the final brace.
43
44A single JSON dictionary mapping each exact entity phrase to its correct label:
45{{
46"""
47
48# --- Load Model and Tokenizer ---
49print(f"Loading tokenizer from {MODEL_REPO_ID}...")
50tokenizer = AutoTokenizer.from_pretrained(MODEL_REPO_ID, trust_remote_code=True)
51if tokenizer.pad_token is None:
52 tokenizer.pad_token = tokenizer.eos_token
53
54print(f"Loading base model and then LoRA adapter from {MODEL_REPO_ID}...")
55# Load the base model first (Qwen2.5-14B-Instruct)
56base_model = AutoModelForCausalLM.from_pretrained(
57 "Qwen/Qwen2.5-14B-Instruct",
58 torch_dtype=torch.bfloat16,
59 device_map="auto",
60 trust_remote_code=True,
61 load_in_4bit=True # Important if trained with QLoRA
62)
63
64# Load the PEFT adapter
65model = PeftModel.from_pretrained(base_model, MODEL_REPO_ID)
66model = model.merge_and_unload() # Merge LoRA weights into the base model for inference
67model.eval() # Set model to evaluation mode
68
69print("Model loaded and merged successfully!")
70
71# --- Inference Function ---
72@torch.no_grad()
73def extract_entities(text: str) -> dict:
74 messages = [
75 {"role": "system", "content": SYSTEM_PROMPT},
76 {"role": "user", "content": USER_CONTEXT_TEMPLATE.format(text=text)}
77 ]
78
79 input_ids = tokenizer.apply_chat_template(
80 messages,
81 add_generation_prompt=True,
82 return_tensors="pt"
83 ).to(model.device)
84
85 generated_ids = model.generate(
86 input_ids,
87 max_new_tokens=GENERATION_MAX_NEW_TOKENS,
88 pad_token_id=tokenizer.eos_token_id,
89 attention_mask=torch.ones_like(input_ids)
90 )
91
92 response_ids = generated_ids[0, input_ids.shape[1]:]
93 model_output = tokenizer.decode(response_ids, skip_special_tokens=True)
94
95 # Basic JSON extraction (you might want a more robust parser)
96 try:
97 start_brace = model_output.find('{')
98 end_brace = model_output.rfind('}')
99 if start_brace != -1 and end_brace != -1 and start_brace < end_brace:
100 json_str = model_output[start_brace : end_brace + 1]
101 # Simple fix for trailing commas if any
102 json_str = json_str.replace(', }', '}')
103 json_str = json_str.replace(',]', ']')
104 return json.loads(json_str)
105 else:
106 print(f"Warning: No valid JSON found in model output: {model_output}")
107 return {}
108 except Exception as e:
109 print(f"Error parsing JSON from model output: {e}")
110 print(f"Raw output: {model_output}")
111 return {}
112
113
114# --- Example Usage ---
115example_text_1 = "Blue carbon habitats in Aotearoa New Zealand—opportunities for conservation, restoration, and carbon sequestration. This study was conducted from January 2023 to June 2024."
116
117print("\n--- Example 1 Inference ---")
118extracted_json_1 = extract_entities(example_text_1)
119print("Extracted Entities (JSON):")
120import json
121print(json.dumps(extracted_json_1, indent=2, ensure_ascii=False))
122
123example_text_2 = "The primary research question was to investigate the efficacy of CRISPR-Cas9 genome editing in maize for drought resistance. Our hypothesis was that edited plants would show improved water retention."
124
125print("\n--- Example 2 Inference ---")
126extracted_json_2 = extract_entities(example_text_2)
127print("Extracted Entities (JSON):")
128print(json.dumps(extracted_json_2, indent=2, ensure_ascii=False))