feat(思维导图助手):优化打包
parent
4b50b6bf4e
commit
9f42a65e9e
|
|
@ -38,11 +38,42 @@ RUN python3 -m pip install -U pip -i https://mirrors.aliyun.com/pypi/simple && \
|
|||
python3 -m pip install \
|
||||
"numpy==1.26.4" \
|
||||
"opencv-python==4.11.0.86" \
|
||||
"pydantic>=2.12,<3" \
|
||||
"modelscope" \
|
||||
"magic-pdf" \
|
||||
boto3 \
|
||||
"pdfminer.six>=20251230" \
|
||||
pypdfium2 \
|
||||
pypdf \
|
||||
reportlab \
|
||||
pdftext \
|
||||
huggingface-hub \
|
||||
json-repair \
|
||||
fast-langdetect \
|
||||
scikit-image \
|
||||
openai \
|
||||
beautifulsoup4 \
|
||||
magika \
|
||||
mineru-vl-utils \
|
||||
qwen-vl-utils \
|
||||
matplotlib \
|
||||
ultralytics \
|
||||
doclayout_yolo==0.0.4 \
|
||||
dill \
|
||||
PyYAML \
|
||||
ftfy \
|
||||
shapely \
|
||||
pyclipper \
|
||||
omegaconf \
|
||||
onnxruntime \
|
||||
python-pptx \
|
||||
python-docx \
|
||||
openpyxl \
|
||||
xlrd \
|
||||
xlwt \
|
||||
pylatexenc \
|
||||
mammoth \
|
||||
-i https://mirrors.aliyun.com/pypi/simple && \
|
||||
python3 -m pip install --force-reinstall --no-cache-dir "pydantic>=2.12,<3" -i https://mirrors.aliyun.com/pypi/simple && \
|
||||
python3 -c "import pydantic; print('pydantic', pydantic.__version__); from pydantic import TypeAdapter; print('pydantic TypeAdapter ok')" && \
|
||||
python3 -m pip cache purge
|
||||
|
||||
WORKDIR /app
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
FROM unis-mindmap-api:latest
|
||||
RUN python3 -m pip install \
|
||||
boto3 \
|
||||
"pdfminer.six>=20251230" \
|
||||
pypdfium2 \
|
||||
pypdf \
|
||||
reportlab \
|
||||
pdftext \
|
||||
huggingface-hub \
|
||||
json-repair \
|
||||
fast-langdetect \
|
||||
scikit-image \
|
||||
openai \
|
||||
beautifulsoup4 \
|
||||
magika \
|
||||
mineru-vl-utils \
|
||||
qwen-vl-utils \
|
||||
matplotlib \
|
||||
ultralytics \
|
||||
doclayout_yolo==0.0.4 \
|
||||
dill \
|
||||
PyYAML \
|
||||
ftfy \
|
||||
shapely \
|
||||
pyclipper \
|
||||
omegaconf \
|
||||
onnxruntime \
|
||||
python-pptx \
|
||||
python-docx \
|
||||
openpyxl \
|
||||
xlrd \
|
||||
xlwt \
|
||||
pylatexenc \
|
||||
mammoth \
|
||||
-i https://mirrors.aliyun.com/pypi/simple && \
|
||||
python3 -m pip cache purge
|
||||
|
|
@ -110,6 +110,7 @@ class ModelSingleton:
|
|||
vllm_llm = vllm.LLM(**kwargs)
|
||||
elif backend == "vllm-async-engine":
|
||||
try:
|
||||
import inspect
|
||||
from vllm.engine.arg_utils import AsyncEngineArgs
|
||||
from vllm.v1.engine.async_llm import AsyncLLM
|
||||
except ImportError:
|
||||
|
|
@ -122,6 +123,8 @@ class ModelSingleton:
|
|||
from mineru_vl_utils import MinerULogitsProcessor
|
||||
kwargs["logits_processors"] = [MinerULogitsProcessor]
|
||||
# 使用kwargs为 vllm初始化参数
|
||||
supported_args = set(inspect.signature(AsyncEngineArgs).parameters)
|
||||
kwargs = {k: v for k, v in kwargs.items() if k in supported_args}
|
||||
vllm_async_llm = AsyncLLM.from_engine_args(AsyncEngineArgs(**kwargs))
|
||||
elif backend == "lmdeploy-engine":
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
VERSION=${VERSION:-$(date +%Y%m%d%H%M%S)}
|
||||
ROOT_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
echo "Building UnisMindMap API image: unis-mindmap-api:${VERSION}"
|
||||
sudo docker build -f docker/china/Dockerfile \
|
||||
-t unis-mindmap-api:${VERSION} \
|
||||
-t unis-mindmap-api:latest \
|
||||
-t mineru:test \
|
||||
.
|
||||
|
||||
echo "Building UnisMindMap Web image: unis-mindmap-web:${VERSION}"
|
||||
sudo docker build -f web_ui/Dockerfile.portable \
|
||||
-t unis-mindmap-web:${VERSION} \
|
||||
-t unis-mindmap-web:latest \
|
||||
web_ui
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
NETWORK=${NETWORK:-unis-ai}
|
||||
API_NAME=${API_NAME:-mineru-api}
|
||||
WEB_NAME=${WEB_NAME:-mindmap-web}
|
||||
WEB_PORT=${WEB_PORT:-9898}
|
||||
MINERU_API_URL=${MINERU_API_URL:-http://${API_NAME}:8000}
|
||||
|
||||
sudo docker network create "$NETWORK" >/dev/null 2>&1 || true
|
||||
sudo docker rm -f "$API_NAME" "$WEB_NAME" >/dev/null 2>&1 || true
|
||||
|
||||
sudo docker run -d --name "$API_NAME" --network "$NETWORK" \
|
||||
--privileged --ipc=host --shm-size=32g \
|
||||
-e MINERU_MODEL_SOURCE=local \
|
||||
-e PYTHONPATH=/app:/usr/local/corex-4.4.0/lib64/python3/dist-packages \
|
||||
unis-mindmap-api:latest \
|
||||
mineru-api --host 0.0.0.0 --port 8000
|
||||
|
||||
sudo docker run -d --name "$WEB_NAME" --network "$NETWORK" \
|
||||
-p "${WEB_PORT}:9898" \
|
||||
-e MINERU_API_URL="$MINERU_API_URL" \
|
||||
unis-mindmap-web:latest
|
||||
|
|
@ -8,13 +8,44 @@ server {
|
|||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
|
||||
location ~* ^/(assets|mindmap/assets)/.*\.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
|
||||
rewrite ^/mindmap/(.*)$ /$1 break;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
location = /mindmap {
|
||||
return 301 /mindmap/;
|
||||
}
|
||||
|
||||
location = /mindmap/api/health {
|
||||
proxy_pass ${MINERU_API_URL}/health;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location = /api/health {
|
||||
proxy_pass ${MINERU_API_URL}/health;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ^~ /mindmap/api/ {
|
||||
rewrite ^/mindmap/api/(.*)$ /api/$1 break;
|
||||
proxy_pass ${MINERU_API_URL};
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 100M;
|
||||
proxy_connect_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location = /file_parse {
|
||||
|
|
@ -30,7 +61,7 @@ server {
|
|||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass ${MINERU_API_URL}/;
|
||||
proxy_pass ${MINERU_API_URL}/api/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
|
@ -40,4 +71,13 @@ server {
|
|||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location ^~ /mindmap/ {
|
||||
rewrite ^/mindmap/(.*)$ /$1 break;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,17 +41,6 @@ export interface MindmapOrganizeProgress extends ParseProgress {
|
|||
result_md?: string | null
|
||||
}
|
||||
|
||||
export interface MindmapLlmConfig {
|
||||
base_url?: string
|
||||
api_key?: string
|
||||
model?: string
|
||||
timeout?: number
|
||||
temperature?: number
|
||||
max_context_tokens?: number
|
||||
max_output_tokens?: number
|
||||
safety_tokens?: number
|
||||
}
|
||||
|
||||
export const documentApi = {
|
||||
/**
|
||||
* 解析文档
|
||||
|
|
@ -84,7 +73,7 @@ export const documentApi = {
|
|||
formData.append('task_id', taskId)
|
||||
}
|
||||
|
||||
return request.post('/api/file_parse', formData, {
|
||||
return request.post('/file_parse', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
...(taskId ? { 'X-Task-ID': taskId } : {})
|
||||
|
|
@ -99,7 +88,7 @@ export const documentApi = {
|
|||
},
|
||||
|
||||
createParseTask(taskId: string): Promise<ParseProgress> {
|
||||
return request.post(`/api/parse_tasks/${encodeURIComponent(taskId)}`).then(result => {
|
||||
return request.post(`/parse_tasks/${encodeURIComponent(taskId)}`).then(result => {
|
||||
return result as unknown as ParseProgress
|
||||
})
|
||||
},
|
||||
|
|
@ -108,30 +97,23 @@ export const documentApi = {
|
|||
* 查询解析进度
|
||||
*/
|
||||
getParseProgress(taskId: string): Promise<ParseProgress> {
|
||||
return request.get(`/api/parse_progress/${taskId}`).then(result => {
|
||||
return request.get(`/parse_progress/${taskId}`).then(result => {
|
||||
return result as unknown as ParseProgress
|
||||
})
|
||||
},
|
||||
|
||||
createMindmapTask(
|
||||
taskId: string,
|
||||
markdown: string,
|
||||
mode = 'smart',
|
||||
prompt?: string,
|
||||
llmConfig?: MindmapLlmConfig
|
||||
): Promise<MindmapOrganizeProgress> {
|
||||
return request.post(`/api/mindmap_tasks/${encodeURIComponent(taskId)}`, {
|
||||
createMindmapTask(taskId: string, markdown: string, mode = 'smart', prompt?: string): Promise<MindmapOrganizeProgress> {
|
||||
return request.post(`/mindmap_tasks/${encodeURIComponent(taskId)}`, {
|
||||
markdown,
|
||||
mode,
|
||||
prompt,
|
||||
llm_config: llmConfig
|
||||
prompt
|
||||
}).then(result => {
|
||||
return result as unknown as MindmapOrganizeProgress
|
||||
})
|
||||
},
|
||||
|
||||
getMindmapProgress(taskId: string): Promise<MindmapOrganizeProgress> {
|
||||
return request.get(`/api/mindmap_progress/${encodeURIComponent(taskId)}`).then(result => {
|
||||
return request.get(`/mindmap_progress/${encodeURIComponent(taskId)}`).then(result => {
|
||||
return result as unknown as MindmapOrganizeProgress
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,24 @@
|
|||
import axios from 'axios'
|
||||
|
||||
// 创建 axios 实例
|
||||
const getApiBaseURL = () => {
|
||||
const pathname = window.location.pathname
|
||||
const basePath = pathname === '/mindmap' || pathname.startsWith('/mindmap/') ? '/mindmap' : ''
|
||||
return `${basePath}/api`
|
||||
}
|
||||
|
||||
// ?? axios ??
|
||||
const request = axios.create({
|
||||
baseURL: '',
|
||||
timeout: 300000, // 5分钟超时
|
||||
baseURL: getApiBaseURL(),
|
||||
timeout: 300000, // 5????
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
// ?????
|
||||
request.interceptors.request.use(
|
||||
(config) => {
|
||||
// 可以在这里添加认证token等
|
||||
// ?????????token?
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
|
|
@ -20,13 +26,13 @@ request.interceptors.request.use(
|
|||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
// ?????
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
return response.data
|
||||
},
|
||||
(error) => {
|
||||
// 统一错误处理
|
||||
// ??????
|
||||
if (error.response) {
|
||||
const serverMessage = error.response.data?.error || error.response.data?.detail
|
||||
if (serverMessage) {
|
||||
|
|
@ -36,34 +42,34 @@ request.interceptors.response.use(
|
|||
|
||||
switch (error.response.status) {
|
||||
case 400:
|
||||
error.message = '请求参数错误'
|
||||
error.message = '??????'
|
||||
break
|
||||
case 401:
|
||||
error.message = '未授权,请重新登录'
|
||||
error.message = '?????????'
|
||||
break
|
||||
case 403:
|
||||
error.message = '拒绝访问'
|
||||
error.message = '????'
|
||||
break
|
||||
case 404:
|
||||
error.message = '请求资源不存在'
|
||||
error.message = '???????'
|
||||
break
|
||||
case 500:
|
||||
error.message = '服务器内部错误'
|
||||
error.message = '???????'
|
||||
break
|
||||
case 502:
|
||||
error.message = '网关错误'
|
||||
error.message = '????'
|
||||
break
|
||||
case 503:
|
||||
error.message = '服务不可用'
|
||||
error.message = '?????'
|
||||
break
|
||||
case 504:
|
||||
error.message = '网关超时'
|
||||
error.message = '????'
|
||||
break
|
||||
default:
|
||||
error.message = `连接错误${error.response.status}`
|
||||
error.message = `????${error.response.status}`
|
||||
}
|
||||
} else {
|
||||
error.message = '网络连接异常'
|
||||
error.message = '??????'
|
||||
}
|
||||
|
||||
return Promise.reject(error)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import vue from '@vitejs/plugin-vue'
|
|||
import { resolve } from 'path'
|
||||
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
|
|
@ -13,8 +14,13 @@ export default defineConfig({
|
|||
port: 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://10.100.52.76:8000',
|
||||
target: process.env.VITE_API_PROXY || 'http://127.0.0.1:8000',
|
||||
changeOrigin: true
|
||||
},
|
||||
'/mindmap/api': {
|
||||
target: process.env.VITE_API_PROXY || 'http://127.0.0.1:8000',
|
||||
changeOrigin: true,
|
||||
rewrite: path => path.replace(/^\/mindmap\/api/, '/api')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -30,4 +36,4 @@ export default defineConfig({
|
|||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue