Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Serving
提交
ce3b0df8
S
Serving
项目概览
PaddlePaddle
/
Serving
大约 1 年 前同步成功
通知
186
Star
833
Fork
253
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
105
列表
看板
标记
里程碑
合并请求
10
Wiki
2
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Serving
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
105
Issue
105
列表
看板
标记
里程碑
合并请求
10
合并请求
10
Pages
分析
分析
仓库分析
DevOps
Wiki
2
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ce3b0df8
编写于
8月 27, 2021
作者:
H
HexToString
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update comment
上级
5a9c03ce
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
38 addition
and
28 deletion
+38
-28
core/configure/proto/server_configure.proto
core/configure/proto/server_configure.proto
+2
-2
core/predictor/framework/bsf-inl.h
core/predictor/framework/bsf-inl.h
+22
-12
core/predictor/framework/bsf.h
core/predictor/framework/bsf.h
+9
-9
core/predictor/framework/infer.cpp
core/predictor/framework/infer.cpp
+4
-4
core/predictor/framework/infer.h
core/predictor/framework/infer.h
+1
-1
未找到文件。
core/configure/proto/server_configure.proto
浏览文件 @
ce3b0df8
...
...
@@ -23,8 +23,8 @@ message EngineDesc {
required
string
model_dir
=
5
;
repeated
int32
gpu_ids
=
6
;
optional
int32
runtime_thread_num
=
7
[
default
=
0
];
optional
int32
batch_infer_size
=
8
[
default
=
0
];
optional
bool
enable_
batch_align
=
9
[
default
=
tru
e
];
optional
int32
batch_infer_size
=
8
[
default
=
32
];
optional
bool
enable_
overrun
=
9
[
default
=
fals
e
];
optional
bool
allow_split_request
=
10
[
default
=
true
];
optional
string
version_file
=
11
;
optional
string
version_type
=
12
;
...
...
core/predictor/framework/bsf-inl.h
100644 → 100755
浏览文件 @
ce3b0df8
...
...
@@ -217,7 +217,7 @@ TaskHandler<TaskT> TaskExecutor<TaskT>::schedule(
}
/*
if (!BatchTasks<TaskT>::check_valid(in, out, _
batch_alig
n)) {
if (!BatchTasks<TaskT>::check_valid(in, out, _
overru
n)) {
LOG(ERROR) << "Invalid input & output";
return TaskHandler<TaskT>::valid_handle();
}
...
...
@@ -271,21 +271,30 @@ bool TaskExecutor<TaskT>::move_task_to_batch(
while
(
!
_task_queue
.
empty
())
{
TaskT
*
task
=
_task_queue
.
front
();
// 由于无法确定fetchVar是否为lod,故单个task不能拆分放到多个batchTask中,否则后续组装很难完成。
// 所以,task不能被拆分,即用户的请求可以合并一起预测,但不能拆分两个小部分去预测。
// 难点:预测前,能够知道被拆成了几个taskmeta,但只有预测后,才知道有多少个fetchvar,多少个lod的fetchvar
// 所以,task中想要创建taskmeta_num* lod的fetchvar num* PaddleBuf(以及Lod)
// 只能在notify_task中,用taskmeta->task去创建,需要在task中加锁。
// 原子操作不可行,因为多个线程必须等待创建好上述的PaddleBuf后才能继续。
// 由于无法确定fetchVar是否为lod(即使输入是非lod,输出也可能是lod)
// 简单的处理方法是:task不能被拆分,即用户的请求可以合并一起预测,但不能拆分两个小部分去预测。
// 只需要设置engine的属性allow_split_request = false即可。
// 复杂的处理方法是允许拆分Task,无论是否包含lod.
// 难点:预测前,能够知道被拆成了几个taskmeta,但只有预测后,才知道有多少个fetchvar,多少个lod的fetchvar
// 所以,task中先要创建taskmeta_num* fetchvar num(lod类型的)个临时PaddleTensor(存储data及Lod)
// 由于多线程调度的单位是taskmeta,故只能在notify_task中,用taskmeta->task去创建
// 此时由于多个taskmeta对应一个task,存在多线程竞争,所以需要在task中加锁。
// 原子操作不可行,因为多个线程必须等待创建好上述的PaddleTensor后才能继续。
// 对于普通的fetch,也需要加锁去创建PaddleTensor,后续才能往里拷贝。
// _batch_align为false时,即使空间小,也会全放入一个完整的Task,允许临时超限。
// _allow_split_request == false,则每个task不会被拆分。
// _overrun表示,异步BatchTasks是否允许单次临时超过限制。
// _overrun为true时,即使BatchTasks剩下1-batch,也会全放入一个完整的Task,允许临时超限。
// _overrun为false时,不允许。
// 对于模型本身有最大Batch限制的情况,应将该值设为false,默认为false。
// 对于模型本身无最大Batch限制,但自己设置了BatchTasks的最大Batch,可以考虑设置为True。
// _allow_split_request == true,则允许拆分task.BatchTasks剩下1-batch,则会从下一个Task中拆出1-Batch
// _allow_split_request == false,则每个task不会被拆分。BatchTasks剩下1-batch会被浪费
// 默认为true,允许拆分task从而使得空间利用率最大。
if
(
!
batchTask
.
get_allow_split_request
())
{
if
(
task
->
batch_size
()
>
batchTask
.
get_rem_size
()
&&
batchTask
.
get_batch_alig
n
())
{
!
batchTask
.
get_overru
n
())
{
break
;
}
}
...
...
@@ -299,6 +308,7 @@ bool TaskExecutor<TaskT>::move_task_to_batch(
// 所以要求该feedvar必须相等,才能合并。
// 否则跳出循环,放入下一个batchTask中。
// 目前没有PaddleTensor和PaddleBuff没有重载==,所以只能比较内存.
// TODO(HexToString): 可以考虑后期支持AutoPadding.
if
(
previous_task
!=
nullptr
)
{
if
(
!
task
->
combine_task_valid
(
previous_task
))
{
break
;
...
...
@@ -366,7 +376,7 @@ int TaskExecutor<TaskT>::work(ThreadContext<TaskT>* context) {
// move_task_to_batch() take the original task from the `_task_queue`
// put the original task into its own Vector<taskmeta>
// the capacity of its own Vector<taskmeta> is decided by `_batch_size` or
// `_
batch_alig
n`
// `_
overru
n`
// merge_tasks() move the imput-data into `_batch_in` from its own
// Vector<taskmeta>.
...
...
@@ -376,7 +386,7 @@ int TaskExecutor<TaskT>::work(ThreadContext<TaskT>* context) {
// `_batch_out`.
// because the predictor`s output is the `_batch_out`
BatchTasks
<
TaskT
>
batchTask
(
_batch_size
,
_
batch_alig
n
,
_allow_split_request
);
_batch_size
,
_
overru
n
,
_allow_split_request
);
if
(
move_task_to_batch
(
batchTask
))
{
batchTask
.
merge_tasks
();
_fn
(
&
batchTask
.
in
(),
&
batchTask
.
out
());
...
...
core/predictor/framework/bsf.h
100644 → 100755
浏览文件 @
ce3b0df8
...
...
@@ -444,11 +444,11 @@ class BatchTasks {
friend
TaskT
;
explicit
BatchTasks
(
size_t
batch_size
,
bool
batch_align
=
tru
e
,
bool
overrun
=
fals
e
,
bool
allow_split_request
=
true
)
:
_batch_size
(
batch_size
),
_rem_size
(
batch_size
),
_
batch_align
(
batch_alig
n
),
_
overrun
(
overru
n
),
_allow_split_request
(
allow_split_request
)
{
_batch_in
.
clear
();
_batch_in_offset
.
clear
();
...
...
@@ -484,10 +484,10 @@ class BatchTasks {
// 能进到此函数的task都是同类task,在该函数之前已保证了这点。
size_t
append_task
(
TaskT
*
task
)
{
size_t
add
=
std
::
min
(
task
->
rem
,
_rem_size
);
// when _
batch_align == fals
e, it means always take a whole task as TaskMeta
// when _
overrun == tru
e, it means always take a whole task as TaskMeta
// we can temporary breakthrough the limit of BatchTask`s capacity
// BatchTask`s capacity is _batch_size or _rem_size
if
(
!
_batch_alig
n
)
{
if
(
_overru
n
)
{
add
=
task
->
rem
;
}
int
start_index
=
task
->
batch_size
()
-
task
->
rem
;
...
...
@@ -883,7 +883,7 @@ class BatchTasks {
const
size_t
get_rem_size
()
{
return
_rem_size
;
}
bool
get_
batch_align
()
{
return
_batch_alig
n
;
}
bool
get_
overrun
()
{
return
_overru
n
;
}
bool
get_allow_split_request
()
{
return
_allow_split_request
;
}
...
...
@@ -905,7 +905,7 @@ class BatchTasks {
size_t
_rem_size
;
size_t
_batch_size
;
bool
_
batch_alig
n
;
bool
_
overru
n
;
bool
_allow_split_request
;
};
...
...
@@ -991,7 +991,7 @@ class TaskExecutor {
_thread_reset_fn
(
NULL
),
_user_thread_contexts
(
NULL
),
_batch_size
(
DEFAULT_BATCH_SIZE
),
_
batch_alig
n
(
false
),
_
overru
n
(
false
),
_fn
(
NULL
)
{
THREAD_MUTEX_INIT
(
&
_mut
,
NULL
);
THREAD_COND_INIT
(
&
_cond
,
NULL
);
...
...
@@ -1012,7 +1012,7 @@ class TaskExecutor {
void
set_batch_size
(
size_t
batch_size
)
{
_batch_size
=
batch_size
;
}
void
set_
batch_align
(
bool
batch_align
)
{
_batch_align
=
batch_alig
n
;
}
void
set_
overrun
(
bool
overrun
)
{
_overrun
=
overru
n
;
}
void
set_allow_split_request
(
bool
allow_split_request
)
{
_allow_split_request
=
allow_split_request
;
...
...
@@ -1068,7 +1068,7 @@ class TaskExecutor {
std
::
vector
<
ThreadContext
<
TaskT
>*>
_thread_contexts
;
size_t
_batch_size
;
bool
_
batch_alig
n
;
bool
_
overru
n
;
bool
_allow_split_request
;
boost
::
function
<
void
(
const
void
*
,
void
*
)
>
_fn
;
...
...
core/predictor/framework/infer.cpp
100644 → 100755
浏览文件 @
ce3b0df8
...
...
@@ -25,7 +25,7 @@ int ReloadableInferEngine::proc_initialize_impl(
_model_dir
=
conf
.
model_dir
();
_infer_thread_num
=
conf
.
runtime_thread_num
();
_infer_batch_size
=
conf
.
batch_infer_size
();
_infer_
batch_align
=
conf
.
enable_batch_alig
n
();
_infer_
overrun
=
conf
.
enable_overru
n
();
_allow_split_request
=
conf
.
allow_split_request
();
_conf
=
conf
;
...
...
@@ -67,8 +67,8 @@ int ReloadableInferEngine::proc_initialize(const configure::EngineDesc& conf,
boost
::
bind
(
&
InferEngine
::
task_infer_impl
,
this
,
_1
,
_2
));
im
::
bsf
::
TaskExecutorVector
<
TaskT
>::
instance
()[
_model_index
].
set_batch_size
(
_infer_batch_size
);
im
::
bsf
::
TaskExecutorVector
<
TaskT
>::
instance
()[
_model_index
].
set_
batch_alig
n
(
_infer_
batch_alig
n
);
im
::
bsf
::
TaskExecutorVector
<
TaskT
>::
instance
()[
_model_index
].
set_
overru
n
(
_infer_
overru
n
);
im
::
bsf
::
TaskExecutorVector
<
TaskT
>::
instance
()[
_model_index
]
.
set_allow_split_request
(
_allow_split_request
);
if
(
im
::
bsf
::
TaskExecutorVector
<
TaskT
>::
instance
()[
_model_index
].
start
(
...
...
@@ -79,7 +79,7 @@ int ReloadableInferEngine::proc_initialize(const configure::EngineDesc& conf,
LOG
(
WARNING
)
<<
"Enable batch schedule framework, thread_num:"
<<
_infer_thread_num
<<
", batch_size:"
<<
_infer_batch_size
<<
", enable_
batch_align:"
<<
_infer_batch_alig
n
<<
", enable_
overrun:"
<<
_infer_overru
n
<<
", allow_split_request:"
<<
_allow_split_request
;
return
0
;
}
...
...
core/predictor/framework/infer.h
浏览文件 @
ce3b0df8
...
...
@@ -163,7 +163,7 @@ class ReloadableInferEngine : public InferEngine {
uint32_t
_infer_batch_size
;
// Need to align batch_size in inferring
bool
_infer_
batch_alig
n
;
bool
_infer_
overru
n
;
// allow to split request in inferring
bool
_allow_split_request
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录