Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5413af8
imporve pruning module
NHZlX Jun 2, 2017
ca55a24
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 2, 2017
18435f2
modify the pruning from reading mask to specify sparsity_ratio
NHZlX Jun 2, 2017
b6eaed0
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 2, 2017
092828f
modify the doc of the interface
NHZlX Jun 5, 2017
1a1c589
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 5, 2017
23a1480
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 5, 2017
1566848
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 6, 2017
a1e1472
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 7, 2017
97a2fde
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 12, 2017
997cef2
tiny modify
NHZlX Jun 14, 2017
23b1a27
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 14, 2017
98e4bb7
Create ParameterUpdaterHook.cpp
NHZlX Jun 14, 2017
4fbec82
Update ParameterUpdaterHook.cpp
NHZlX Jun 14, 2017
5405dc0
Create ParameterUpdaterHook.cpp
NHZlX Jun 14, 2017
6248e56
merge from remote
NHZlX Jun 15, 2017
fc9e3e4
explain the sparsity ratio
NHZlX Jun 16, 2017
a3ada68
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 16, 2017
885275e
Update ParameterUpdaterHook.cpp
NHZlX Jun 16, 2017
1a82e7d
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 19, 2017
15bf6e0
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 21, 2017
1eab8cc
modify the annotations of HookAttribute, Variable declaration
NHZlX Jun 21, 2017
aaf11fa
modify the format
NHZlX Jun 21, 2017
a266292
modify format
NHZlX Jun 21, 2017
43771ad
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 22, 2017
fdde4ef
modify some topo
NHZlX Jun 23, 2017
561c456
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
NHZlX Jun 23, 2017
1d6b859
modity topo
NHZlX Jun 23, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 49 additions & 75 deletions paddle/parameter/ParameterUpdaterHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ limitations under the License. */

#include "ParameterUpdaterHook.h"

#include <algorithm>
#include <atomic>
#include <fstream>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <vector>

#include "paddle/math/Vector.h"
#include "paddle/parameter/Parameter.h"
Expand All @@ -29,40 +31,21 @@ namespace paddle {

/**
* The static pruning hook
*
* Static means user load a mask map before training started. This map will
* define which link/weight between neural is disabled.
* Static means user specific a sparsity_ratio before training start, and the
* network will prune the parameters based on the sparsity_ratio. More deatils
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: specific -> specify, start -> started
More deatils can see -> More details can be found

* can see https://arxiv.org/pdf/1506.02626.pdf.
*/

class StaticPruningHook : public IParameterUpdaterHook {
public:
/**
* The Mask Map Header.
* The map file started with this header.
*
* In Version 0, reset file will be:
* contains header.size bit, each bit means such weight is enabled or not.
* if bit is 1, then such weight is enabled.
* at end, the file will round to byte, and the low bits of end byte will be
* filled by zero.
*
*/
struct StaticMaskHeader {
uint32_t version;
size_t size;
} __attribute__((__packed__));

explicit StaticPruningHook(const std::string& mask_filename) : initCount_(0) {
bool ok = this->loadMaskFile(mask_filename);
if (!ok) {
LOG(WARNING) << "Fail to load mask file " << mask_filename
<< " in current directory, searching in init_model_path";
std::string combineMaskFilename =
path::join(FLAGS_init_model_path, mask_filename);
CHECK(this->loadMaskFile(combineMaskFilename))
<< "Cannot load " << mask_filename << " in ./" << mask_filename
<< " and " << combineMaskFilename;
}
VLOG(3) << mask_filename << " mask size = " << this->mask_.size();
explicit StaticPruningHook(const ParameterUpdaterHookConfig& hookConfig)
: initCount_(0) {
sparsityRatio_ = hookConfig.sparsity_ratio();
}

static bool sortPairAscend(const std::pair<real, size_t>& pair1,
const std::pair<real, size_t>& pair2) {
return pair1.first > pair2.first;
}

void update(Parameter* para) {
Expand All @@ -73,62 +56,53 @@ class StaticPruningHook : public IParameterUpdaterHook {
}
}

void init(Parameter* para) {
size_t initCount = this->initCount_.fetch_add(1);
CHECK_EQ(initCount, 0UL) << "Currently the StaticPruningHook must invoke "
"in same ParamterUpdater";
VLOG(3) << "Initialize Parameter " << para;
SetDevice device(para->getDeviceId());
void generateMask(Parameter* para) {
VectorPtr vec = para->getBuf(PARAMETER_VALUE);
maskTemp_ = Vector::create(para->getSize(), false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maskTemp_改成局部变量

maskTemp_->zeroMem();
real* dataPtr = maskTemp_->getData();
size_t sparsityNum = para->getSize() * (1 - sparsityRatio_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sparsityRatio_这个指的是非零元还是零元的ratio?我看左边的第72行,原先的定义看起来是非零元的ratio,这里为什么换了?
···
for (size_t i = 0; i < para->getSize() * sparsityRatio_; i++)
···

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是0元的ratio,mask初始值全为0, 这里要做的是将非0元素的mask 设置为1,所以为(1 - sparsityRatio_), 这里的sparsityNum确实起的不是太好,会修改一下


auto maskVec = Vector::create(this->mask_.size(), false);
{ // Initialize maskVec with float mask vector
real* dataPtr = maskVec->getData();
size_t i = 0;
for (bool m : mask_) {
dataPtr[i++] = m ? 1.0 : 0.0;
}
}
VectorPtr vecCpu = Vector::create(para->getSize(), false);
vecCpu->copyFrom(*vec);
std::vector<std::pair<real, size_t>> param;

for (size_t i = 0; i < para->getSize(); i++)
param.push_back(std::make_pair(fabs(vecCpu->getData()[i]), i));

std::partial_sort(param.begin(),
param.begin() + sparsityNum,
param.end(),
sortPairAscend);
for (size_t i = 0; i < sparsityNum; i++) dataPtr[param[i].second] = 1.0;

// Currently just use a mask vector for hack.
// @TODO(yuyang18): Implemented the mask operation in vector.
if (para->useGpu()) {
maskVec_ = Vector::create(this->mask_.size(), para->useGpu());
maskVec_->copyFrom(*maskVec);
maskVec_ = Vector::create(para->getSize(), para->useGpu());
maskVec_->copyFrom(*maskTemp_);
} else {
maskVec_ = maskVec;
maskVec_ = maskTemp_;
}
}

void init(Parameter* para) {
generateMask(para);
size_t initCount = this->initCount_.fetch_add(1);
CHECK_EQ(initCount, 0UL) << "Currently the StaticPruningHook must invoke "
"in same ParamterUpdater";
VLOG(3) << "Initialize Parameter " << para;
SetDevice device(para->getDeviceId());

auto& vec = para->getBuf(PARAMETER_VALUE);
vec->dotMul(*maskVec_);
}

private:
bool loadMaskFile(const std::string& mask_filename) {
std::ifstream fin;
fin.open(mask_filename);
if (fin.is_open()) {
StaticMaskHeader header;
fin.read(reinterpret_cast<char*>(&header), sizeof(StaticMaskHeader));
CHECK_EQ(header.version, 0UL);
mask_.resize(header.size);
uint8_t buf;
for (size_t i = 0; i < header.size; ++i, buf <<= 1) {
if (i % 8 == 0) {
fin.read(reinterpret_cast<char*>(&buf), sizeof(uint8_t));
}
mask_[i] = buf & 0x80;
}
fin.close();
return true;
} else {
return false;
}
}

SameThreadChecker updateThreadChecker_;
std::atomic<size_t> initCount_;
VectorPtr maskVec_;
std::vector<bool> mask_;
VectorPtr maskTemp_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看看能不能不把maskTemp做成成员变量。

real sparsityRatio_;
};

IParameterUpdaterHook::IParameterUpdaterHook() {}
Expand Down Expand Up @@ -166,10 +140,10 @@ static IParameterUpdaterHook* createImpl(
const ParameterUpdaterHookConfig& config) {
auto& type = config.type();
if (type == "pruning") {
if (config.has_purning_mask_filename()) {
return new StaticPruningHook(config.purning_mask_filename());
}
return new StaticPruningHook(config);
}

LOG(FATAL) << "Unknown Hook type: " << type;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确认一下,如果没有配置hook时,是不会调用该函数的吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这块是为了保证如果指定的hook type不在我们提供的当中的话,会报错。 python v2 /python/paddle/trainer/config_parser.py ParameterHook 处有关于hook type的检测,但是未来也有其他不同过python方式来调用这个的吧。

return nullptr;
}

Expand Down
3 changes: 2 additions & 1 deletion proto/ParameterConfig.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ enum ParameterInitStrategy {
}

message ParameterUpdaterHookConfig {
// hook type such as 'pruning'
required string type = 1;
optional string purning_mask_filename = 2;
optional double sparsity_ratio = 2 [default = 0.8];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里要注释清楚sparsity_ratio指的是非零还是零元的。比如default=0.8指的是80%的零元?实际上我看到sparsity_ratio的第一反应以为是非零元的占比。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hedaoyuan 嗯,好

}

message ParameterConfig {
Expand Down
10 changes: 5 additions & 5 deletions python/paddle/trainer/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3189,11 +3189,11 @@ def Layer(name, type, **xargs):
@config_func
def ParameterHook(type, **kwargs):
if type == 'pruning':
mask_filename = kwargs.get('mask_filename', None)
assert mask_filename is not None
hook = ParameterUpdaterHookConfig()
hook.type = type
hook.purning_mask_filename = mask_filename
sparsity_ratio = kwargs.get('sparsity_ratio', None)
if sparsity_ratio is not None:
hook.sparsity_ratio = sparsity_ratio
return hook
else:
return None
Expand Down Expand Up @@ -3300,13 +3300,13 @@ def Parameter(name,

if update_hooks is not None:
if hasattr(update_hooks, '__call__'):
update_hooks = update_hooks(para.name)
update_hooks = update_hooks()

if isinstance(update_hooks, list):
for hook in update_hooks:
para.update_hooks.extend([hook])
else:
para.update_hooks.extend(update_hooks)
para.update_hooks.extend([update_hooks])

g_parameter_map[name] = para

Expand Down
37 changes: 35 additions & 2 deletions python/paddle/trainer_config_helpers/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

from paddle.trainer.config_parser import *
__all__ = [
'ParamAttr', 'ExtraAttr', 'ParameterAttribute', 'ExtraLayerAttribute'
'HookAttr', 'ParamAttr', 'ExtraAttr', 'ParameterAttribute',
'ExtraLayerAttribute'
]


Expand Down Expand Up @@ -55,6 +56,33 @@ def is_compatible_with(x, Type):
return False


class HookAttribute(object):
"""
Hook Attribute object. The hook is an auxiliary operation that occurs
during network propagation.
NOTE: IT IS A HIGH LEVEL USER INTERFACE.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

最好能说明下Hook是用来干什么的,作用的对象。另外,我认为这个NOTE就没有必要了。


:param type: Hook type, eg: 'pruning'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的注释会用来生成api文档,所以最好写详细点。比如所有支持的type类型,以及参考的论文工作。

:type type: string

:param sparsity_ratio: Must be specified if hook type is 'pruning'
:type sparsity_ratio: float or None

"""

def __init__(self, type, sparsity_ratio=None):
self.type = type
self.sparsity_ratio = sparsity_ratio
if self.sparsity_ratio is not None:
assert is_compatible_with(
self.sparsity_ratio,
float), 'sparisity_ratio must be float type'
assert self.sparsity_ratio <= 1 and self.sparsity_ratio >= 0, 'sparisity must be a flaot between [0, 1] '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'sparisity must be a flaot between [0, 1] ' -> 'sparisity_ratio must be a float between [0, 1] ',错误提示与变量名保持一致,另外还有typo。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


def __call__(self):
return ParameterHook(self.type, sparsity_ratio=self.sparsity_ratio)


class ParameterAttribute(object):
"""
Parameter Attributes object. To fine-tuning network training process, user
Expand Down Expand Up @@ -109,7 +137,8 @@ def __init__(self,
learning_rate=None,
momentum=None,
gradient_clipping_threshold=None,
sparse_update=False):
sparse_update=False,
update_hooks=None):
self.attr = {}

if is_static:
Expand Down Expand Up @@ -162,6 +191,9 @@ def __init__(self,
self.attr['gradient_clipping_threshold'] = \
gradient_clipping_threshold

if update_hooks:
self.attr['update_hooks'] = update_hooks

def set_default_parameter_name(self, name):
"""
Set default parameter name. If parameter not set, then will use default
Expand Down Expand Up @@ -237,5 +269,6 @@ def to_kwargs(attr):
return attr.attr


HookAttr = HookAttribute
ParamAttr = ParameterAttribute
ExtraAttr = ExtraLayerAttribute
2 changes: 2 additions & 0 deletions python/paddle/v2/attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
__all__ = [
"Param",
"Extra",
"Hook",
]

Param = paddle.trainer_config_helpers.attrs.ParameterAttribute
Extra = paddle.trainer_config_helpers.attrs.ExtraLayerAttribute
Hook = paddle.trainer_config_helpers.attrs.HookAttribute

for each in paddle.trainer_config_helpers.attrs.__all__:
globals()[each] = getattr(paddle.trainer_config_helpers.attrs, each)
Expand Down