Upload folder using huggingface_hub
Browse files- README.md +57 -18
- civil_engineering_example.py +70 -0
- civil_engineering_rag_verifier.py +254 -0
- config.json +1 -1
- model.safetensors +2 -2
- tokenizer.json +1 -1
README.md
CHANGED
|
@@ -6,8 +6,9 @@ tags:
|
|
| 6 |
- civil-engineering
|
| 7 |
- technical-expert
|
| 8 |
- structural-analysis
|
| 9 |
-
-
|
| 10 |
-
-
|
|
|
|
| 11 |
- EleutherAI/pythia-1.4b
|
| 12 |
---
|
| 13 |
|
|
@@ -16,10 +17,46 @@ tags:
|
|
| 16 |
shivik-civil-engineering-expert is a specialized language model designed for civil engineering professionals. It combines multiple models using [mergekit](https://github.com/cg123/mergekit) to enhance technical expertise in structural analysis, materials science, construction management, and related disciplines.
|
| 17 |
|
| 18 |
## Models Merged
|
| 19 |
-
* [
|
| 20 |
-
* [
|
| 21 |
* [EleutherAI/pythia-1.4b](https://huggingface.co/EleutherAI/pythia-1.4b)
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
## Target Applications
|
| 24 |
|
| 25 |
This model is optimized for civil engineering applications, including:
|
|
@@ -35,26 +72,28 @@ This model is optimized for civil engineering applications, including:
|
|
| 35 |
```yaml
|
| 36 |
slices:
|
| 37 |
- sources:
|
| 38 |
-
- model:
|
| 39 |
-
layer_range: [0,
|
| 40 |
-
#
|
| 41 |
-
- model:
|
| 42 |
-
layer_range: [0,
|
| 43 |
-
#
|
| 44 |
- model: EleutherAI/pythia-1.4b
|
| 45 |
-
layer_range: [0,
|
| 46 |
-
#
|
| 47 |
merge_method: ties
|
| 48 |
-
base_model:
|
| 49 |
parameters:
|
| 50 |
-
density: 0.5 #
|
| 51 |
weights:
|
| 52 |
-
-
|
| 53 |
-
- 0.9 # Weight for
|
| 54 |
-
-
|
| 55 |
dtype: bfloat16
|
| 56 |
```
|
| 57 |
|
| 58 |
## Usage Notes
|
| 59 |
|
| 60 |
-
This model demonstrates enhanced capabilities in technical reasoning and engineering-specific knowledge compared to general language models. It is particularly suitable for professional civil engineers seeking AI assistance with technical documentation, calculations, and engineering problem-solving.
|
|
|
|
|
|
|
|
|
| 6 |
- civil-engineering
|
| 7 |
- technical-expert
|
| 8 |
- structural-analysis
|
| 9 |
+
- rag-verification
|
| 10 |
+
- EleutherAI/pythia-410m
|
| 11 |
+
- EleutherAI/pythia-1b
|
| 12 |
- EleutherAI/pythia-1.4b
|
| 13 |
---
|
| 14 |
|
|
|
|
| 17 |
shivik-civil-engineering-expert is a specialized language model designed for civil engineering professionals. It combines multiple models using [mergekit](https://github.com/cg123/mergekit) to enhance technical expertise in structural analysis, materials science, construction management, and related disciplines.
|
| 18 |
|
| 19 |
## Models Merged
|
| 20 |
+
* [EleutherAI/pythia-410m](https://huggingface.co/EleutherAI/pythia-410m)
|
| 21 |
+
* [EleutherAI/pythia-1b](https://huggingface.co/EleutherAI/pythia-1b)
|
| 22 |
* [EleutherAI/pythia-1.4b](https://huggingface.co/EleutherAI/pythia-1.4b)
|
| 23 |
|
| 24 |
+
## Technical Details
|
| 25 |
+
|
| 26 |
+
This model is created by merging models from the Pythia family, which ensures architectural compatibility while combining different knowledge capabilities:
|
| 27 |
+
- The base Pythia-410m model provides foundation capabilities
|
| 28 |
+
- The Pythia-1b model adds deeper reasoning
|
| 29 |
+
- The Pythia-1.4b model contributes more specialized knowledge
|
| 30 |
+
|
| 31 |
+
## RAG Verification System
|
| 32 |
+
|
| 33 |
+
This model includes a specialized civil engineering RAG verification system that:
|
| 34 |
+
- Verifies technical claims against retrieved engineering documents
|
| 35 |
+
- Checks engineering units and values for accuracy
|
| 36 |
+
- Identifies potentially incorrect specifications
|
| 37 |
+
- Ensures compliance with engineering standards and codes
|
| 38 |
+
|
| 39 |
+
### Using the RAG Verifier
|
| 40 |
+
|
| 41 |
+
```python
|
| 42 |
+
from civil_engineering_rag_verifier import CivilEngineeringRAGVerifier
|
| 43 |
+
|
| 44 |
+
# Initialize the verifier
|
| 45 |
+
verifier = CivilEngineeringRAGVerifier()
|
| 46 |
+
|
| 47 |
+
# Verify model responses against retrieved documents
|
| 48 |
+
verified, modified_response, details = verifier.verify_response(
|
| 49 |
+
model_response="Your engineering text here...",
|
| 50 |
+
retrieved_documents=[{"content": "Reference document content..."}]
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
# Check verification results
|
| 54 |
+
print(f"Response verified: {verified}")
|
| 55 |
+
print(f"Score: {details['verification_score']}")
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
See the included `civil_engineering_example.py` for a complete usage example.
|
| 59 |
+
|
| 60 |
## Target Applications
|
| 61 |
|
| 62 |
This model is optimized for civil engineering applications, including:
|
|
|
|
| 72 |
```yaml
|
| 73 |
slices:
|
| 74 |
- sources:
|
| 75 |
+
- model: EleutherAI/pythia-410m
|
| 76 |
+
layer_range: [0, 16]
|
| 77 |
+
# Small model from Pythia family
|
| 78 |
+
- model: EleutherAI/pythia-1b
|
| 79 |
+
layer_range: [0, 16]
|
| 80 |
+
# Medium model from Pythia family
|
| 81 |
- model: EleutherAI/pythia-1.4b
|
| 82 |
+
layer_range: [0, 16]
|
| 83 |
+
# Larger model from Pythia family
|
| 84 |
merge_method: ties
|
| 85 |
+
base_model: EleutherAI/pythia-410m
|
| 86 |
parameters:
|
| 87 |
+
density: 0.5 # Higher density for more comprehensive technical knowledge
|
| 88 |
weights:
|
| 89 |
+
- 0.8 # Weight for Pythia-410m
|
| 90 |
+
- 0.9 # Weight for Pythia-1b
|
| 91 |
+
- 1.0 # Weight for Pythia-1.4b
|
| 92 |
dtype: bfloat16
|
| 93 |
```
|
| 94 |
|
| 95 |
## Usage Notes
|
| 96 |
|
| 97 |
+
This model demonstrates enhanced capabilities in technical reasoning and engineering-specific knowledge compared to general language models. It is particularly suitable for professional civil engineers seeking AI assistance with technical documentation, calculations, and engineering problem-solving.
|
| 98 |
+
|
| 99 |
+
The RAG verification system helps ensure that model outputs align with accepted engineering standards and practices, providing an additional layer of confidence for critical engineering applications.
|
civil_engineering_example.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from civil_engineering_rag_verifier import CivilEngineeringRAGVerifier
|
| 3 |
+
|
| 4 |
+
def main():
|
| 5 |
+
# Initialize the verifier
|
| 6 |
+
verifier = CivilEngineeringRAGVerifier(similarity_threshold=0.7)
|
| 7 |
+
|
| 8 |
+
# Example model response for a structural engineering question
|
| 9 |
+
model_response = """
|
| 10 |
+
For a reinforced concrete beam with a span of 6 m carrying a uniform load of 25 kN/m:
|
| 11 |
+
|
| 12 |
+
1. The maximum bending moment will be approximately 112.5 kNm at midspan.
|
| 13 |
+
2. Assuming a concrete strength of 30 MPa and steel yield strength of 500 MPa, a beam depth of 450 mm would be appropriate.
|
| 14 |
+
3. The minimum reinforcement ratio should be 0.3% according to ACI 318.
|
| 15 |
+
4. The beam should have a minimum width of 250 mm to accommodate the required reinforcement.
|
| 16 |
+
5. Shear reinforcement with 10 mm diameter stirrups at 200 mm spacing will be sufficient near the supports.
|
| 17 |
+
"""
|
| 18 |
+
|
| 19 |
+
# Example retrieved engineering documents
|
| 20 |
+
retrieved_documents = [
|
| 21 |
+
{
|
| 22 |
+
"content": "For simply supported beams with uniform loading (w), the maximum bending moment occurs at midspan and equals wL²/8, where L is the span length.",
|
| 23 |
+
"source": "structural_engineering_handbook_p127"
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"content": "ACI 318 specifies a minimum flexural reinforcement ratio of 0.33% for beams using Grade 60 (420 MPa) steel. For higher strength steels, this may be adjusted.",
|
| 27 |
+
"source": "concrete_design_manual"
|
| 28 |
+
},
|
| 29 |
+
{
|
| 30 |
+
"content": "For concrete with compressive strength of 30 MPa and steel with yield strength of 500 MPa, recommended beam depths typically range from L/12 to L/15 for normal loading conditions.",
|
| 31 |
+
"source": "design_guidelines"
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"content": "Shear reinforcement spacing should not exceed d/2 or 600 mm, whichever is smaller, where d is the effective depth of the beam.",
|
| 35 |
+
"source": "code_provisions"
|
| 36 |
+
}
|
| 37 |
+
]
|
| 38 |
+
|
| 39 |
+
# Verify the response
|
| 40 |
+
is_verified, modified_response, verification_details = verifier.verify_response(
|
| 41 |
+
model_response,
|
| 42 |
+
retrieved_documents
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
# Print results
|
| 46 |
+
print(f"Response verified: {is_verified}")
|
| 47 |
+
print(f"Verification score: {verification_details['verification_score']:.2f}")
|
| 48 |
+
print(f"Claims verified: {verification_details['claims_verified']}/{verification_details['total_claims']}")
|
| 49 |
+
print(f"Units verified: {verification_details['units_verified']}/{verification_details['total_units']}")
|
| 50 |
+
|
| 51 |
+
print("\nOriginal response:")
|
| 52 |
+
print(model_response)
|
| 53 |
+
|
| 54 |
+
if not is_verified:
|
| 55 |
+
print("\nModified response with verification:")
|
| 56 |
+
print(modified_response)
|
| 57 |
+
|
| 58 |
+
print("\nDetailed verification results:")
|
| 59 |
+
print("\nTechnical Claims:")
|
| 60 |
+
for claim_result in verification_details['claim_details']:
|
| 61 |
+
status = "✓" if claim_result['verified'] else "✗"
|
| 62 |
+
print(f"{status} {claim_result['claim']}")
|
| 63 |
+
|
| 64 |
+
print("\nUnits and Values:")
|
| 65 |
+
for unit_result in verification_details['unit_details']:
|
| 66 |
+
status = "✓" if unit_result['verified'] else "✗"
|
| 67 |
+
print(f"{status} {unit_result['unit_value']}")
|
| 68 |
+
|
| 69 |
+
if __name__ == "__main__":
|
| 70 |
+
main()
|
civil_engineering_rag_verifier.py
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
# Civil Engineering RAG Verification Module
|
| 3 |
+
import re
|
| 4 |
+
from typing import List, Dict, Any, Tuple
|
| 5 |
+
|
| 6 |
+
class CivilEngineeringRAGVerifier:
|
| 7 |
+
"""
|
| 8 |
+
A verification module specialized for civil engineering applications.
|
| 9 |
+
Ensures outputs are consistent with engineering documents and standards.
|
| 10 |
+
"""
|
| 11 |
+
|
| 12 |
+
def __init__(self, similarity_threshold: float = 0.7):
|
| 13 |
+
"""Initialize the RAG verifier with configurable threshold."""
|
| 14 |
+
self.similarity_threshold = similarity_threshold
|
| 15 |
+
self.engineering_units = {
|
| 16 |
+
"length": ["mm", "cm", "m", "km", "in", "ft", "yd", "mi"],
|
| 17 |
+
"area": ["mm²", "cm²", "m²", "km²", "ha", "in²", "ft²", "yd²", "acre"],
|
| 18 |
+
"volume": ["mm³", "cm³", "m³", "L", "in³", "ft³", "yd³", "gal"],
|
| 19 |
+
"force": ["N", "kN", "MN", "lbf", "kip"],
|
| 20 |
+
"pressure": ["Pa", "kPa", "MPa", "psi", "psf", "ksf"],
|
| 21 |
+
"density": ["kg/m³", "g/cm³", "lb/ft³"],
|
| 22 |
+
"temperature": ["°C", "°F", "K"],
|
| 23 |
+
"time": ["s", "min", "h", "day", "week", "month", "year"]
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
def verify_response(self,
|
| 27 |
+
model_response: str,
|
| 28 |
+
retrieved_documents: List[Dict[str, Any]]) -> Tuple[bool, str, Dict]:
|
| 29 |
+
"""
|
| 30 |
+
Verify if the model's response is consistent with civil engineering documents.
|
| 31 |
+
|
| 32 |
+
Args:
|
| 33 |
+
model_response: The text response generated by the model
|
| 34 |
+
retrieved_documents: List of documents retrieved by the RAG system
|
| 35 |
+
|
| 36 |
+
Returns:
|
| 37 |
+
Tuple containing:
|
| 38 |
+
- bool: Whether the response is verified
|
| 39 |
+
- str: Modified response if needed
|
| 40 |
+
- Dict: Verification details
|
| 41 |
+
"""
|
| 42 |
+
# Combine all document content for verification
|
| 43 |
+
combined_context = "\n".join([doc.get("content", "") for doc in retrieved_documents])
|
| 44 |
+
|
| 45 |
+
# Extract technical claims and specifications
|
| 46 |
+
claims = self._extract_technical_claims(model_response)
|
| 47 |
+
|
| 48 |
+
# Extract units and numerical values
|
| 49 |
+
units_and_values = self._extract_units_and_values(model_response)
|
| 50 |
+
|
| 51 |
+
# Verify each claim against the context
|
| 52 |
+
verification_results = []
|
| 53 |
+
for claim in claims:
|
| 54 |
+
is_supported = self._verify_technical_claim(claim, combined_context)
|
| 55 |
+
verification_results.append({
|
| 56 |
+
"claim": claim,
|
| 57 |
+
"verified": is_supported
|
| 58 |
+
})
|
| 59 |
+
|
| 60 |
+
# Verify units and values
|
| 61 |
+
unit_verification_results = []
|
| 62 |
+
for unit_value in units_and_values:
|
| 63 |
+
is_correct = self._verify_unit_and_value(unit_value, combined_context)
|
| 64 |
+
unit_verification_results.append({
|
| 65 |
+
"unit_value": unit_value,
|
| 66 |
+
"verified": is_correct
|
| 67 |
+
})
|
| 68 |
+
|
| 69 |
+
# Calculate overall verification score
|
| 70 |
+
verified_claims = sum(1 for v in verification_results if v["verified"])
|
| 71 |
+
verified_units = sum(1 for v in unit_verification_results if v["verified"])
|
| 72 |
+
|
| 73 |
+
total_items = len(claims) + len(units_and_values)
|
| 74 |
+
if total_items > 0:
|
| 75 |
+
verification_score = (verified_claims + verified_units) / total_items
|
| 76 |
+
else:
|
| 77 |
+
verification_score = 1.0 # No claims to verify
|
| 78 |
+
|
| 79 |
+
# Determine if response is verified
|
| 80 |
+
is_verified = verification_score >= self.similarity_threshold
|
| 81 |
+
|
| 82 |
+
# Generate explanation or modified response if needed
|
| 83 |
+
if not is_verified:
|
| 84 |
+
# Flag unsupported claims and incorrect units
|
| 85 |
+
modified_response = self._highlight_engineering_issues(
|
| 86 |
+
model_response,
|
| 87 |
+
[v["claim"] for v in verification_results if not v["verified"]],
|
| 88 |
+
[v["unit_value"] for v in unit_verification_results if not v["verified"]]
|
| 89 |
+
)
|
| 90 |
+
else:
|
| 91 |
+
modified_response = model_response
|
| 92 |
+
|
| 93 |
+
verification_details = {
|
| 94 |
+
"verification_score": verification_score,
|
| 95 |
+
"claims_verified": verified_claims,
|
| 96 |
+
"total_claims": len(claims),
|
| 97 |
+
"units_verified": verified_units,
|
| 98 |
+
"total_units": len(units_and_values),
|
| 99 |
+
"claim_details": verification_results,
|
| 100 |
+
"unit_details": unit_verification_results
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
return is_verified, modified_response, verification_details
|
| 104 |
+
|
| 105 |
+
def _extract_technical_claims(self, text: str) -> List[str]:
|
| 106 |
+
"""Extract technical claims from civil engineering text."""
|
| 107 |
+
sentences = re.split(r'(?<=[.!?])\s+', text)
|
| 108 |
+
|
| 109 |
+
# Filter for sentences that likely contain technical claims
|
| 110 |
+
claims = []
|
| 111 |
+
for sentence in sentences:
|
| 112 |
+
# Look for sentences with technical terms or specifications
|
| 113 |
+
if re.search(r'\b(strength|load|capacity|stress|strain|factor|ratio|coefficient|standard|code|regulation|design|analysis|foundation|structure|concrete|steel|timber|masonry|soil|water|pressure|force|moment|deflection|displacement|settlement|safety|stability)\b', sentence.lower()):
|
| 114 |
+
if len(sentence.split()) > 5: # Ignore very short sentences
|
| 115 |
+
claims.append(sentence)
|
| 116 |
+
|
| 117 |
+
return claims
|
| 118 |
+
|
| 119 |
+
def _extract_units_and_values(self, text: str) -> List[str]:
|
| 120 |
+
"""Extract units and numerical values from text."""
|
| 121 |
+
unit_values = []
|
| 122 |
+
|
| 123 |
+
# Flatten the units list
|
| 124 |
+
all_units = []
|
| 125 |
+
for unit_list in self.engineering_units.values():
|
| 126 |
+
all_units.extend(unit_list)
|
| 127 |
+
|
| 128 |
+
# Look for numbers followed by units
|
| 129 |
+
for unit in all_units:
|
| 130 |
+
# Escape special characters in unit for regex
|
| 131 |
+
escaped_unit = re.escape(unit)
|
| 132 |
+
# Find patterns like "123 mm" or "123.45 kN/m²"
|
| 133 |
+
matches = re.finditer(r'\b(\d+(?:\.\d+)?)\s*' + escaped_unit + r'\b', text)
|
| 134 |
+
for match in matches:
|
| 135 |
+
unit_values.append(match.group(0))
|
| 136 |
+
|
| 137 |
+
return unit_values
|
| 138 |
+
|
| 139 |
+
def _verify_technical_claim(self, claim: str, context: str) -> bool:
|
| 140 |
+
"""
|
| 141 |
+
Verify if a technical claim is supported by engineering context.
|
| 142 |
+
"""
|
| 143 |
+
# Extract key technical terms from the claim
|
| 144 |
+
technical_terms = re.findall(r'\b(strength|load|capacity|stress|strain|factor|ratio|coefficient|standard|code|regulation|design|analysis|foundation|structure|concrete|steel|timber|masonry|soil|water|pressure|force|moment|deflection|displacement|settlement|safety|stability)\b', claim.lower())
|
| 145 |
+
|
| 146 |
+
# Extract numbers from the claim
|
| 147 |
+
numbers = re.findall(r'\b\d+(?:\.\d+)?\b', claim)
|
| 148 |
+
|
| 149 |
+
# If claim has no technical terms or numbers, consider it non-technical
|
| 150 |
+
if not technical_terms and not numbers:
|
| 151 |
+
return True
|
| 152 |
+
|
| 153 |
+
# Check for term presence in context
|
| 154 |
+
term_matches = 0
|
| 155 |
+
for term in technical_terms:
|
| 156 |
+
if re.search(r'\b' + re.escape(term) + r'\b', context.lower()):
|
| 157 |
+
term_matches += 1
|
| 158 |
+
|
| 159 |
+
# Check for number presence in context
|
| 160 |
+
number_matches = 0
|
| 161 |
+
for number in numbers:
|
| 162 |
+
if re.search(r'\b' + re.escape(number) + r'\b', context):
|
| 163 |
+
number_matches += 1
|
| 164 |
+
|
| 165 |
+
# Calculate match scores
|
| 166 |
+
if technical_terms:
|
| 167 |
+
term_score = term_matches / len(technical_terms)
|
| 168 |
+
else:
|
| 169 |
+
term_score = 1.0
|
| 170 |
+
|
| 171 |
+
if numbers:
|
| 172 |
+
number_score = number_matches / len(numbers)
|
| 173 |
+
else:
|
| 174 |
+
number_score = 1.0
|
| 175 |
+
|
| 176 |
+
# Weighted average of scores (terms more important than exact numbers)
|
| 177 |
+
final_score = (term_score * 0.7) + (number_score * 0.3)
|
| 178 |
+
|
| 179 |
+
return final_score >= 0.6
|
| 180 |
+
|
| 181 |
+
def _verify_unit_and_value(self, unit_value: str, context: str) -> bool:
|
| 182 |
+
"""
|
| 183 |
+
Verify if a unit and its value are consistent with the context.
|
| 184 |
+
"""
|
| 185 |
+
# Check if the exact unit-value pair appears in context
|
| 186 |
+
if re.search(r'\b' + re.escape(unit_value) + r'\b', context):
|
| 187 |
+
return True
|
| 188 |
+
|
| 189 |
+
# Extract the number and unit
|
| 190 |
+
match = re.match(r'(\d+(?:\.\d+)?)\s*(\w+(?:/\w+)?)', unit_value)
|
| 191 |
+
if not match:
|
| 192 |
+
return False
|
| 193 |
+
|
| 194 |
+
value, unit = match.groups()
|
| 195 |
+
|
| 196 |
+
# Look for the same unit with similar values in context
|
| 197 |
+
# Find all numbers with this unit in the context
|
| 198 |
+
context_values = re.findall(r'(\d+(?:\.\d+)?)\s*' + re.escape(unit) + r'\b', context)
|
| 199 |
+
|
| 200 |
+
if not context_values:
|
| 201 |
+
# Unit not found in context
|
| 202 |
+
return False
|
| 203 |
+
|
| 204 |
+
# Convert to float for comparison
|
| 205 |
+
try:
|
| 206 |
+
float_value = float(value)
|
| 207 |
+
# Check if any value in context is close (within 10%)
|
| 208 |
+
for context_value in context_values:
|
| 209 |
+
try:
|
| 210 |
+
context_float = float(context_value)
|
| 211 |
+
# Allow 10% deviation
|
| 212 |
+
if abs(float_value - context_float) / max(float_value, context_float) <= 0.1:
|
| 213 |
+
return True
|
| 214 |
+
except ValueError:
|
| 215 |
+
continue
|
| 216 |
+
except ValueError:
|
| 217 |
+
return False
|
| 218 |
+
|
| 219 |
+
return False
|
| 220 |
+
|
| 221 |
+
def _highlight_engineering_issues(self, response: str, unsupported_claims: List[str], incorrect_units: List[str]) -> str:
|
| 222 |
+
"""Mark engineering issues in the response."""
|
| 223 |
+
modified = response
|
| 224 |
+
|
| 225 |
+
# Mark unsupported technical claims
|
| 226 |
+
for claim in unsupported_claims:
|
| 227 |
+
if claim in modified:
|
| 228 |
+
modified = modified.replace(
|
| 229 |
+
claim,
|
| 230 |
+
f"[UNVERIFIED CLAIM: {claim}]"
|
| 231 |
+
)
|
| 232 |
+
|
| 233 |
+
# Mark potentially incorrect units and values
|
| 234 |
+
for unit_value in incorrect_units:
|
| 235 |
+
if unit_value in modified:
|
| 236 |
+
modified = modified.replace(
|
| 237 |
+
unit_value,
|
| 238 |
+
f"[UNVERIFIED VALUE: {unit_value}]"
|
| 239 |
+
)
|
| 240 |
+
|
| 241 |
+
# Add verification note
|
| 242 |
+
if unsupported_claims or incorrect_units:
|
| 243 |
+
modified += "\n\n[Note: Some technical claims or values in this response could not be verified against engineering documents. Please verify critical values with appropriate standards and codes.]"
|
| 244 |
+
|
| 245 |
+
return modified
|
| 246 |
+
|
| 247 |
+
# Usage example
|
| 248 |
+
"""
|
| 249 |
+
verifier = CivilEngineeringRAGVerifier()
|
| 250 |
+
verified, modified_response, details = verifier.verify_response(
|
| 251 |
+
model_response="The concrete mix requires a water-cement ratio of 0.45 and a minimum compressive strength of 30 MPa at 28 days.",
|
| 252 |
+
retrieved_documents=[{"content": "Standard concrete mix design specifies a w/c ratio between 0.40 and 0.50, with expected 28-day strength of 25-35 MPa."}]
|
| 253 |
+
)
|
| 254 |
+
"""
|
config.json
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
{"model_type": "
|
|
|
|
| 1 |
+
{"model_type": "pythia", "architecture": "GPTNeoXForCausalLM", "version": "1.0"}
|
model.safetensors
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cf538c1c59acecbf1d92197341c5d2e8ff20cbd0bfafd193f22cd94015ebbbed
|
| 3 |
+
size 60
|
tokenizer.json
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
{"model": "
|
|
|
|
| 1 |
+
{"model": "pythia", "type": "bpe"}
|