tddf commited on
Commit
5aecba1
·
verified ·
1 Parent(s): b6335f5

Upload 5 files

Browse files
Files changed (5) hide show
  1. .gitattributes +35 -35
  2. Dockerfile +18 -20
  3. README.md +13 -20
  4. app.py.txt +73 -0
  5. requirements.txt.txt +4 -0
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
Dockerfile CHANGED
@@ -1,20 +1,18 @@
1
- FROM python:3.13.5-slim
2
-
3
- WORKDIR /app
4
-
5
- RUN apt-get update && apt-get install -y \
6
- build-essential \
7
- curl \
8
- git \
9
- && rm -rf /var/lib/apt/lists/*
10
-
11
- COPY requirements.txt ./
12
- COPY src/ ./src/
13
-
14
- RUN pip3 install -r requirements.txt
15
-
16
- EXPOSE 8501
17
-
18
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
19
-
20
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
1
+ FROM python:3.10-slim
2
+
3
+ # Создаём непривилегированного пользователя (требование Hugging Face)
4
+ RUN useradd -m -u 1000 user
5
+ USER user
6
+ ENV HOME=/home/user PATH=/home/user/.local/bin:$PATH
7
+
8
+ # Устанавливаем рабочую директорию
9
+ WORKDIR $HOME/app
10
+
11
+ # Копируем все файлы из текущей папки в контейнер
12
+ COPY --chown=user . $HOME/app
13
+
14
+ # Устанавливаем зависимости Python
15
+ RUN pip install --no-cache-dir -r requirements.txt
16
+
17
+ # Запускаем Streamlit на порту 7860 (этот порт ожидает Hugging Face)
18
+ CMD ["streamlit", "run", "app.py", "--server.port=7860", "--server.address=0.0.0.0"]
 
 
README.md CHANGED
@@ -1,20 +1,13 @@
1
- ---
2
- title: End
3
- emoji: 🚀
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Streamlit template space
12
- license: apache-2.0
13
- ---
14
-
15
- # Welcome to Streamlit!
16
-
17
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
18
-
19
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
20
- forums](https://discuss.streamlit.io).
 
1
+ ---
2
+ title: English OCR App
3
+ emoji: 🔤
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: docker
7
+ app_file: app.py
8
+ pinned: false
9
+ ---
10
+
11
+ # English OCR with LightOnOCR
12
+
13
+ Upload an image containing English text, and the model will extract it.
 
 
 
 
 
 
 
app.py.txt ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import os
3
+ import streamlit as st
4
+ import torch
5
+ from PIL import Image
6
+ from transformers import AutoProcessor, AutoModelForSeq2SeqLM
7
+
8
+ # --- Настройка кэша для модели (чтобы не скачивать при каждом запуске) ---
9
+ # Hugging Face Spaces даёт нам постоянную папку /data, если включить Persistent Storage.
10
+ # Если /data существует, используем её, иначе временную папку /tmp.
11
+ CACHE_DIR = "/data/.huggingface" if os.path.exists("/data") else "/tmp/.huggingface"
12
+ os.makedirs(CACHE_DIR, exist_ok=True)
13
+
14
+ # --- Функция загрузки модели с кэшированием через Streamlit ---
15
+ @st.cache_resource # Эта декорация сохраняет модель в памяти между запусками
16
+ def load_model():
17
+ model_name = "lightonai/LightOnOCR-1B-1025"
18
+
19
+ # Определяем, есть ли GPU (CUDA)
20
+ device = "cuda" if torch.cuda.is_available() else "cpu"
21
+ st.write(f"Using device: {device}") # Для отладки в логах
22
+
23
+ # Загружаем процессор (преобразует изображение в тензоры) и модель
24
+ processor = AutoProcessor.from_pretrained(model_name, cache_dir=CACHE_DIR)
25
+ model = AutoModelForSeq2SeqLM.from_pretrained(model_name, cache_dir=CACHE_DIR)
26
+ model = model.to(device) # Перемещаем модель на GPU/CPU
27
+
28
+ return processor, model, device
29
+
30
+ # --- Интерфейс загрузки изображения ---
31
+ def load_image():
32
+ uploaded_file = st.file_uploader(
33
+ 'Выберите изображение с английским текстом',
34
+ type=['png', 'jpg', 'jpeg']
35
+ )
36
+ if uploaded_file is not None:
37
+ # Читаем байты и показываем картинку
38
+ image_data = uploaded_file.getvalue()
39
+ st.image(image_data, use_column_width=True)
40
+ # Конвертируем в RGB (на всякий случай)
41
+ return Image.open(io.BytesIO(image_data)).convert('RGB')
42
+ return None
43
+
44
+ # --- Заголовок приложения ---
45
+ st.title('🇬🇧 Распознавание английского текста (LightOnOCR)')
46
+
47
+ # --- Загружаем модель (один раз) ---
48
+ with st.spinner('Загрузка модели... Это может занять 1-2 минуты при первом запуске'):
49
+ processor, model, device = load_model()
50
+
51
+ # --- Загружаем изображение ---
52
+ img = load_image()
53
+
54
+ # --- Кнопка распознавания ---
55
+ if st.button('Распознать текст') and img is not None:
56
+ with st.spinner('Распознавание...'):
57
+ # Преобразуем изображение в формат, понятный модели
58
+ inputs = processor(images=img, return_tensors="pt").to(device)
59
+
60
+ # Генерируем текст (без вычисления градиентов, чтобы экономить память)
61
+ with torch.no_grad():
62
+ generated_ids = model.generate(
63
+ **inputs,
64
+ max_new_tokens=512, # Максимум символов на выходе
65
+ do_sample=False, # Детерминированный режим (лучше для OCR)
66
+ num_beams=1
67
+ )
68
+ # Декодируем ID токенов обратно в строку
69
+ generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
70
+
71
+ st.success('✅ Распознано!')
72
+ st.markdown('**📝 Текст на изображении:**')
73
+ st.markdown(f'`{generated_text}`')
requirements.txt.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ streamlit
2
+ torch
3
+ transformers
4
+ pillow