Update app.py
Browse files
app.py
CHANGED
|
@@ -28,25 +28,35 @@ def translate(text, source_lang, target_lang):
|
|
| 28 |
"Norwegian": "nob_Latn"
|
| 29 |
}
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
return_tensors="pt",
|
| 34 |
-
truncation=True,
|
| 35 |
-
max_length=512
|
| 36 |
-
)
|
| 37 |
-
|
| 38 |
-
if hasattr(model, 'device'):
|
| 39 |
-
inputs = {k: v.to(model.device) for k, v in inputs.items()}
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
-
|
| 49 |
-
return result
|
| 50 |
|
| 51 |
def swap_languages(src, tgt, input_txt, output_txt):
|
| 52 |
return tgt, src, output_txt, input_txt
|
|
@@ -67,170 +77,150 @@ def load_file(file):
|
|
| 67 |
except Exception as e:
|
| 68 |
return f"Error reading file: {str(e)}"
|
| 69 |
|
| 70 |
-
def translate_file(file, source_lang, target_lang):
|
| 71 |
-
content = load_file(file)
|
| 72 |
-
if content and not content.startswith("Error"):
|
| 73 |
-
return translate(content, source_lang, target_lang)
|
| 74 |
-
return content
|
| 75 |
-
|
| 76 |
custom_css = """
|
| 77 |
.gradio-container {
|
| 78 |
-
max-width:
|
| 79 |
-
|
| 80 |
}
|
| 81 |
-
.
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
}
|
| 86 |
-
.
|
| 87 |
-
min-width: 48px !important;
|
| 88 |
-
height: 48px !important;
|
| 89 |
-
border-radius: 50% !important;
|
| 90 |
background: white !important;
|
| 91 |
-
border:
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
}
|
| 94 |
-
.text-area {
|
| 95 |
border: none !important;
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
}
|
| 100 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
background: white !important;
|
| 102 |
-
border
|
| 103 |
box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
|
|
|
|
|
|
|
|
|
|
| 104 |
}
|
| 105 |
-
.
|
| 106 |
-
border-left: 3px solid #1a73e8 !important;
|
| 107 |
-
padding-left: 12px !important;
|
| 108 |
-
margin: 8px 0 !important;
|
| 109 |
background: #f8f9fa !important;
|
| 110 |
-
border-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
}
|
| 112 |
"""
|
| 113 |
|
| 114 |
with gr.Blocks(css=custom_css, theme=gr.themes.Default()) as demo:
|
| 115 |
|
| 116 |
-
|
|
|
|
|
|
|
| 117 |
with gr.Column(scale=1):
|
| 118 |
-
with gr.
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
show_label=False,
|
|
|
|
|
|
|
| 123 |
container=False,
|
| 124 |
-
elem_classes="
|
| 125 |
)
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
file_input = gr.File(
|
| 136 |
-
label="Upload text file",
|
| 137 |
-
file_types=[".txt", ".md", ".doc"],
|
| 138 |
-
type="filepath"
|
| 139 |
-
)
|
| 140 |
|
| 141 |
-
with gr.Column(scale=0, min_width=
|
| 142 |
-
gr.
|
| 143 |
-
|
| 144 |
|
| 145 |
with gr.Column(scale=1):
|
| 146 |
-
with gr.
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
show_label=False,
|
|
|
|
|
|
|
| 151 |
container=False,
|
| 152 |
-
elem_classes="
|
|
|
|
| 153 |
)
|
| 154 |
-
|
| 155 |
-
output_text = gr.Textbox(
|
| 156 |
-
placeholder="Translation",
|
| 157 |
-
show_label=False,
|
| 158 |
-
lines=12,
|
| 159 |
-
container=False,
|
| 160 |
-
elem_classes="text-area",
|
| 161 |
-
interactive=False
|
| 162 |
-
)
|
| 163 |
-
|
| 164 |
-
download_btn = gr.File(
|
| 165 |
-
label="Download translation",
|
| 166 |
-
visible=False
|
| 167 |
-
)
|
| 168 |
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
)
|
| 175 |
|
| 176 |
-
with gr.Accordion("Example
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
the formation while maintaining kick tolerance within acceptable limits.
|
| 188 |
-
</div>
|
| 189 |
-
"""
|
| 190 |
-
)
|
| 191 |
-
|
| 192 |
-
with gr.Column():
|
| 193 |
-
gr.Markdown(
|
| 194 |
-
"""
|
| 195 |
-
<div class='example-box'>
|
| 196 |
-
<b>Reservoir Analysis Example:</b><br><br>
|
| 197 |
-
Reservoaret viser utmerket permeabilitet på 250 millidarcy og porøsitet på 22 prosent basert på
|
| 198 |
-
kjerneanalyse. Formasjonsvannsmetningen er estimert til 35 prosent, noe som indikerer betydelig
|
| 199 |
-
hydrokarbonpotensial. Seismiske data bekrefter en strukturell felle med estimert areal på 12
|
| 200 |
-
kvadratkilometer. Produktivitetstester viser stabilisert oljeproduksjon på 3,400 fat per dag ved
|
| 201 |
-
optimaliseringstrykk på 2,100 psi.
|
| 202 |
-
</div>
|
| 203 |
-
"""
|
| 204 |
-
)
|
| 205 |
-
|
| 206 |
-
with gr.Row():
|
| 207 |
-
with gr.Column():
|
| 208 |
-
gr.Markdown(
|
| 209 |
-
"""
|
| 210 |
-
<div class='example-box'>
|
| 211 |
-
<b>Safety Procedure Example:</b><br><br>
|
| 212 |
-
All personnel must complete H2S safety training before entering the drilling site. Emergency response
|
| 213 |
-
equipment including breathing apparatus and wind direction indicators must be positioned at designated
|
| 214 |
-
muster points. Wellhead pressure monitoring systems shall be checked every 4 hours during critical
|
| 215 |
-
operations. In case of gas detection exceeding 10 ppm, immediate evacuation procedures must be initiated
|
| 216 |
-
according to the site emergency response plan.
|
| 217 |
-
</div>
|
| 218 |
-
"""
|
| 219 |
-
)
|
| 220 |
-
|
| 221 |
-
with gr.Column():
|
| 222 |
-
gr.Markdown(
|
| 223 |
-
"""
|
| 224 |
-
<div class='example-box'>
|
| 225 |
-
<b>Equipment Specification Example:</b><br><br>
|
| 226 |
-
Undervannsproduktjonssystemet består av en vertikalt juletræ med maksimal arbeidstrykk på 10,000 psi
|
| 227 |
-
og temperaturbegrensning på 150 grader Celsius. Produksjonsrøret er 7-tommers krom-legering designet
|
| 228 |
-
for korrosive miljøer. Flytkontrollen opprettholdes ved bruk av subsea multifase meter og akustisk
|
| 229 |
-
sanddeteksjon. Systemet er utstyrt med redundante sikkerhetsfunksjoner inkludert automatiske
|
| 230 |
-
nedstengningsventiler og trykkovervåkingssystemer.
|
| 231 |
-
</div>
|
| 232 |
-
"""
|
| 233 |
-
)
|
| 234 |
|
| 235 |
input_text.change(
|
| 236 |
fn=translate,
|
|
|
|
| 28 |
"Norwegian": "nob_Latn"
|
| 29 |
}
|
| 30 |
|
| 31 |
+
sentences = text.split('\n')
|
| 32 |
+
translated_sentences = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
+
for sentence in sentences:
|
| 35 |
+
if not sentence.strip():
|
| 36 |
+
translated_sentences.append("")
|
| 37 |
+
continue
|
| 38 |
+
|
| 39 |
+
inputs = tokenizer(
|
| 40 |
+
sentence,
|
| 41 |
+
return_tensors="pt",
|
| 42 |
+
truncation=True,
|
| 43 |
+
max_length=512
|
| 44 |
+
)
|
| 45 |
+
|
| 46 |
+
if hasattr(model, 'device'):
|
| 47 |
+
inputs = {k: v.to(model.device) for k, v in inputs.items()}
|
| 48 |
+
|
| 49 |
+
outputs = model.generate(
|
| 50 |
+
**inputs,
|
| 51 |
+
forced_bos_token_id=tokenizer.convert_tokens_to_ids(lang_map[target_lang]),
|
| 52 |
+
max_length=512,
|
| 53 |
+
num_beams=5
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
result = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
| 57 |
+
translated_sentences.append(result)
|
| 58 |
|
| 59 |
+
return '\n'.join(translated_sentences)
|
|
|
|
| 60 |
|
| 61 |
def swap_languages(src, tgt, input_txt, output_txt):
|
| 62 |
return tgt, src, output_txt, input_txt
|
|
|
|
| 77 |
except Exception as e:
|
| 78 |
return f"Error reading file: {str(e)}"
|
| 79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
custom_css = """
|
| 81 |
.gradio-container {
|
| 82 |
+
max-width: 1100px !important;
|
| 83 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
|
| 84 |
}
|
| 85 |
+
.main-container {
|
| 86 |
+
background: #f6f7f8 !important;
|
| 87 |
+
padding: 0 !important;
|
| 88 |
+
border-radius: 0 !important;
|
| 89 |
}
|
| 90 |
+
.translate-box {
|
|
|
|
|
|
|
|
|
|
| 91 |
background: white !important;
|
| 92 |
+
border-radius: 5px !important;
|
| 93 |
+
padding: 0 !important;
|
| 94 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.08) !important;
|
| 95 |
+
margin: 20px 0 !important;
|
| 96 |
+
}
|
| 97 |
+
.lang-header {
|
| 98 |
+
padding: 16px 20px !important;
|
| 99 |
+
border-bottom: 1px solid #e8eaed !important;
|
| 100 |
+
background: #fafafa !important;
|
| 101 |
+
}
|
| 102 |
+
.lang-selector {
|
| 103 |
+
border: none !important;
|
| 104 |
+
background: transparent !important;
|
| 105 |
+
font-size: 15px !important;
|
| 106 |
+
font-weight: 500 !important;
|
| 107 |
+
color: #333 !important;
|
| 108 |
}
|
| 109 |
+
.text-area textarea {
|
| 110 |
border: none !important;
|
| 111 |
+
font-size: 17px !important;
|
| 112 |
+
line-height: 1.7 !important;
|
| 113 |
+
padding: 20px !important;
|
| 114 |
+
min-height: 200px !important;
|
| 115 |
+
}
|
| 116 |
+
.swap-container {
|
| 117 |
+
display: flex !important;
|
| 118 |
+
align-items: center !important;
|
| 119 |
+
justify-content: center !important;
|
| 120 |
+
padding: 20px 0 !important;
|
| 121 |
}
|
| 122 |
+
.swap-btn {
|
| 123 |
+
width: 44px !important;
|
| 124 |
+
height: 44px !important;
|
| 125 |
+
min-width: 44px !important;
|
| 126 |
+
border-radius: 50% !important;
|
| 127 |
background: white !important;
|
| 128 |
+
border: 1px solid #d1d5db !important;
|
| 129 |
box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
|
| 130 |
+
font-size: 18px !important;
|
| 131 |
+
color: #0f6fff !important;
|
| 132 |
+
cursor: pointer !important;
|
| 133 |
}
|
| 134 |
+
.swap-btn:hover {
|
|
|
|
|
|
|
|
|
|
| 135 |
background: #f8f9fa !important;
|
| 136 |
+
border-color: #0f6fff !important;
|
| 137 |
+
}
|
| 138 |
+
.footer-info {
|
| 139 |
+
text-align: center !important;
|
| 140 |
+
color: #999 !important;
|
| 141 |
+
font-size: 13px !important;
|
| 142 |
+
padding: 20px !important;
|
| 143 |
}
|
| 144 |
"""
|
| 145 |
|
| 146 |
with gr.Blocks(css=custom_css, theme=gr.themes.Default()) as demo:
|
| 147 |
|
| 148 |
+
gr.HTML("<div style='height: 20px'></div>")
|
| 149 |
+
|
| 150 |
+
with gr.Row():
|
| 151 |
with gr.Column(scale=1):
|
| 152 |
+
with gr.Group(elem_classes="translate-box"):
|
| 153 |
+
with gr.Row(elem_classes="lang-header"):
|
| 154 |
+
source_lang = gr.Dropdown(
|
| 155 |
+
choices=["English", "Norwegian"],
|
| 156 |
+
value="English",
|
| 157 |
+
show_label=False,
|
| 158 |
+
container=False,
|
| 159 |
+
elem_classes="lang-selector",
|
| 160 |
+
scale=1
|
| 161 |
+
)
|
| 162 |
+
|
| 163 |
+
input_text = gr.Textbox(
|
| 164 |
+
placeholder="Type to translate",
|
| 165 |
show_label=False,
|
| 166 |
+
lines=8,
|
| 167 |
+
max_lines=20,
|
| 168 |
container=False,
|
| 169 |
+
elem_classes="text-area"
|
| 170 |
)
|
| 171 |
+
|
| 172 |
+
with gr.Row(visible=True):
|
| 173 |
+
file_input = gr.File(
|
| 174 |
+
label="",
|
| 175 |
+
file_types=[".txt"],
|
| 176 |
+
type="filepath",
|
| 177 |
+
scale=1,
|
| 178 |
+
container=False
|
| 179 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
|
| 181 |
+
with gr.Column(scale=0, min_width=100):
|
| 182 |
+
with gr.Row(elem_classes="swap-container"):
|
| 183 |
+
swap_btn = gr.Button("⇄", elem_classes="swap-btn")
|
| 184 |
|
| 185 |
with gr.Column(scale=1):
|
| 186 |
+
with gr.Group(elem_classes="translate-box"):
|
| 187 |
+
with gr.Row(elem_classes="lang-header"):
|
| 188 |
+
target_lang = gr.Dropdown(
|
| 189 |
+
choices=["English", "Norwegian"],
|
| 190 |
+
value="Norwegian",
|
| 191 |
+
show_label=False,
|
| 192 |
+
container=False,
|
| 193 |
+
elem_classes="lang-selector",
|
| 194 |
+
scale=1
|
| 195 |
+
)
|
| 196 |
+
|
| 197 |
+
output_text = gr.Textbox(
|
| 198 |
+
placeholder="Translation",
|
| 199 |
show_label=False,
|
| 200 |
+
lines=8,
|
| 201 |
+
max_lines=20,
|
| 202 |
container=False,
|
| 203 |
+
elem_classes="text-area",
|
| 204 |
+
interactive=False
|
| 205 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
|
| 207 |
+
gr.HTML(
|
| 208 |
+
"<div class='footer-info'>"
|
| 209 |
+
"Oil & Gas Translation • English ↔ Norwegian"
|
| 210 |
+
"</div>"
|
| 211 |
+
)
|
|
|
|
| 212 |
|
| 213 |
+
with gr.Accordion("Example Sentences", open=False):
|
| 214 |
+
gr.Examples(
|
| 215 |
+
examples=[
|
| 216 |
+
["The drilling operation at well site A-15 encountered unexpected high-pressure zones at 3,247 meters depth, requiring immediate adjustment of mud weight from 1.65 to 1.82 specific gravity to maintain wellbore stability and prevent potential kicks.", "English", "Norwegian"],
|
| 217 |
+
["Reservoaret viser utmerket permeabilitet på 250 millidarcy og porøsitet på 22 prosent basert på kjerneanalyse, noe som indikerer betydelig hydrokarbonpotensial med estimert oljemetning på 65 prosent.", "Norwegian", "English"],
|
| 218 |
+
["The subsea production system consists of a vertical Christmas tree rated for 10,000 psi working pressure and 150 degrees Celsius temperature, equipped with redundant safety features including automatic shutdown valves and real-time pressure monitoring systems.", "English", "Norwegian"],
|
| 219 |
+
["Seismiske data bekrefter tilstedeværelsen av en strukturell felle med estimert areal på 12 kvadratkilometer, og produktivitetstester viser stabilisert oljeproduksjon på 3,400 fat per dag ved optimaliseringstrykk på 2,100 psi.", "Norwegian", "English"],
|
| 220 |
+
["Emergency response procedures require all personnel to complete H2S safety training before site access, with breathing apparatus and wind indicators positioned at designated muster points, and immediate evacuation protocols activated when gas detection exceeds 10 ppm concentration levels.", "English", "Norwegian"]
|
| 221 |
+
],
|
| 222 |
+
inputs=[input_text, source_lang, target_lang],
|
| 223 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
|
| 225 |
input_text.change(
|
| 226 |
fn=translate,
|