TensorFlow Estimator to CerebrasEstimator
On This Page
TensorFlow Estimator to CerebrasEstimator¶
This section presents a step-by-step walk-through showing how to convert your TensorFlow code from using TensorFlow Estimator to using CerebrasEstimator.
Consider that your TensorFlow code is already using TensorFlow Estimator, and is similar to the following:
def train_input_fn(batch_size):
iris_dtype = np.dtype([("img", "float32", 4), ("lbl", "int32", 1)])
data = np.genfromtxt("./data/iris_training.csv", dtype=iris_dtype, delimiter=",")
dataset = tf.data.Dataset.from_tensor_slices((data["img"][:], data["lbl"][:]))
dataset = dataset.shuffle(1000).repeat(30).batch(batch_size)
return dataset
def model_fn(features, labels, mode=tf.estimator.ModeKeys.TRAIN, params=None):
""" Two layer fully connected model """
policy = Policy("infer_float32_vars") if mixed_precision else None
net = tf.keras.layers.Dense(256, activation=tf.nn.relu, dtype=policy)(features)
tf.summary.tensor_summary(name="summary1", tensor=net)
net = tf.keras.layers.Dense(128, activation=tf.nn.relu, dtype=policy)(net)
tf.summary.tensor_summary(name="summary2", tensor=net)
logits = tf.keras.layers.Dense(params["num_classes"], dtype=policy)(net)
learning_rate = tf.constant(params["lr"])
if mode in (tf.estimator.ModeKeys.TRAIN, tf.estimator.ModeKeys.EVAL):
loss_op = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
)
train_op = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate
).minimize(loss_op, global_step=tf.train.get_global_step())
spec = tf.estimator.EstimatorSpec(
mode=mode,
loss=loss_op,
train_op=train_op,
eval_metric_ops={"metric": tf.metrics.mean(values=logits)},
)
return spec
hook = tf.train.ProfilerHook(save_steps=100)
est = tf.estimator.Estimator(model_fn, params, model_dir="./out")
est.train(lambda inputfn: input_fn(batch_size), hooks=hook, steps=None)
Step 1: Model function¶
Go through your code (model_fn
and train
function) and remove all summaries, eval_metrics and hooks.
def train_input_fn(batch_size):
iris_dtype = np.dtype([("img", "float32", 4), ("lbl", "int32", 1)])
data = np.genfromtxt("./data/iris_training.csv", dtype=iris_dtype, delimiter=",")
dataset = tf.data.Dataset.from_tensor_slices((data["img"][:], data["lbl"][:]))
dataset = dataset.shuffle(1000).repeat(30).batch(batch_size)
return dataset
def model_fn(features, labels, mode=tf.estimator.ModeKeys.TRAIN, params=None):
""" Two layer fully connected model """
policy = Policy("infer_float32_vars") if mixed_precision else None
net = tf.keras.layers.Dense(256, activation=tf.nn.relu, dtype=policy)(features)
tf.summary.tensor_summary(name="summary1", tensor=net)
net = tf.keras.layers.Dense(128, activation=tf.nn.relu, dtype=policy)(net)
tf.summary.tensor_summary(name="summary2", tensor=net)
logits = tf.keras.layers.Dense(params["num_classes"], dtype=policy)(net)
learning_rate = tf.constant(params["lr"])
if mode in (tf.estimator.ModeKeys.TRAIN, tf.estimator.ModeKeys.EVAL):
loss_op = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
)
train_op = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate
).minimize(loss_op, global_step=tf.train.get_global_step())
spec = tf.estimator.EstimatorSpec(mode=mode, loss=loss_op, train_op=train_op)
return spec
hook = tf.train.ProfilerHook(save_steps=100)
est = tf.estimator.Estimator(model_fn, params, model_dir="./out")
est.train(lambda inputfn: input_fn(batch_size), hooks=hook, steps=None)
Step 2: Input function¶
Ensure that the input_fn
satisfies conditions mentioned in the Input function differences. For example, make sure that the following are true:
The only input into the function is params.
The batches outputted have a fixed
batch_size
, andThe dataset sends an infinite number of samples (using
repeat
).Make sure that your
train
function uses the newinput_fn
and trains for the correct number of steps.
The modified code should now look something like this:
def train_input_fn(params):
batch_size = params["batch_size"]
iris_dtype = np.dtype([("img", "float32", 4), ("lbl", "int32", 1)])
data = np.genfromtxt("./data/iris_training.csv", dtype=iris_dtype, delimiter=",")
dataset = tf.data.Dataset.from_tensor_slices((data["img"][:], data["lbl"][:]))
dataset = dataset.shuffle(1000).repeat().batch(batch_size, drop_remainder=True)
return dataset
def model_fn(features, labels, mode=tf.estimator.ModeKeys.TRAIN, params=None):
""" Two layer fully connected model """
policy = Policy("infer_float32_vars") if mixed_precision else None
net = tf.keras.layers.Dense(256, activation=tf.nn.relu, dtype=policy)(features)
net = tf.keras.layers.Dense(128, activation=tf.nn.relu, dtype=policy)(net)
logits = tf.keras.layers.Dense(params["num_classes"], dtype=policy)(net)
learning_rate = tf.constant(params["lr"])
if mode in (tf.estimator.ModeKeys.TRAIN, tf.estimator.ModeKeys.EVAL):
loss_op = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
)
train_op = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate
).minimize(loss_op, global_step=tf.train.get_global_step())
spec = tf.estimator.EstimatorSpec(mode=mode, loss=loss_op, train_op=train_op)
return spec
est = tf.estimator.Estimator(model_fn, params, model_dir="./out")
est.train(input_fn, steps=10000)
Step 3: Use CerebrasEstimator¶
Next, replace tf.estimator.Estimator
with CerebrasEstimator
.
def train_input_fn(params):
batch_size = params["batch_size"]
iris_dtype = np.dtype([("img", "float32", 4), ("lbl", "int32", "")])
data = np.genfromtxt("./data/iris_training.csv", dtype=iris_dtype, delimiter=",")
dataset = tf.data.Dataset.from_tensor_slices((data["img"][:], data["lbl"][:]))
dataset = dataset.shuffle(1000).repeat().batch(batch_size, drop_remainder=True)
return dataset
def model_fn(features, labels, mode=tf.estimator.ModeKeys.TRAIN, params=None):
""" Two layer fully connected model """
policy = Policy("infer_float32_vars") if mixed_precision else None
net = tf.keras.layers.Dense(256, activation=tf.nn.relu, dtype=policy)(features)
net = tf.keras.layers.Dense(128, activation=tf.nn.relu, dtype=policy)(net)
logits = tf.keras.layers.Dense(params["num_classes"], dtype=policy)(net)
learning_rate = tf.constant(params["lr"])
if mode in (tf.estimator.ModeKeys.TRAIN, tf.estimator.ModeKeys.EVAL):
loss_op = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
)
train_op = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate
).minimize(loss_op, global_step=tf.train.get_global_step())
spec = tf.estimator.EstimatorSpec(mode=mode, loss=loss_op, train_op=train_op)
return spec
est = CerebrasEstimator(
model_fn, config=config, params=params, model_dir="./out", use_cs=True
)
est.train(input_fn, steps=10000)
Step 4: Edit RunConfig¶
Add or replace RunConfig
with CSRunConfig
and ensure that the three Cerebras-specific import
statements are present.
from cerebras.models.common.estimator.tf.cs_estimator import CerebrasEstimator
from cerebras.models.common.estimator.tf.run_config import CSRunConfig
from cerebras.tf.cs_slurm_cluster_resolver import CSSlurmClusterResolver
config = CSRunConfig(cs_ip=ip, save_checkpoints_steps=1000, log_step_count_steps=10000)
def train_input_fn(params):
batch_size = params["batch_size"]
iris_dtype = np.dtype([("img", "float32", 4), ("lbl", "int32", "")])
data = np.genfromtxt("./data/iris_training.csv", dtype=iris_dtype, delimiter=",")
dataset = tf.data.Dataset.from_tensor_slices((data["img"][:], data["lbl"][:]))
dataset = dataset.shuffle(1000).repeat().batch(batch_size, drop_remainder=True)
return dataset
def model_fn(features, labels, mode=tf.estimator.ModeKeys.TRAIN, params=None):
""" Two layer fully connected model """
policy = Policy("infer_float32_vars") if mixed_precision else None
net = tf.keras.layers.Dense(256, activation=tf.nn.relu, dtype=policy)(features)
net = tf.keras.layers.Dense(128, activation=tf.nn.relu, dtype=policy)(net)
logits = tf.keras.layers.Dense(params["num_classes"], dtype=policy)(net)
learning_rate = tf.constant(params["lr"])
if mode in (tf.estimator.ModeKeys.TRAIN, tf.estimator.ModeKeys.EVAL):
loss_op = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
)
train_op = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate
).minimize(loss_op, global_step=tf.train.get_global_step())
spec = tf.estimator.EstimatorSpec(mode=mode, loss=loss_op, train_op=train_op)
return spec
est = CerebrasEstimator(
model_fn, config=config, params=params, model_dir="./out", use_cs=True
)
est.train(input_fn, steps=10000)
Step 5: Ensure mixed precision¶
Finally, ensure that your model is running in Mixed Precision, using the tf.keras Mixed Precision policy.
def model_fn(features, labels, mode=tf.estimator.ModeKeys.TRAIN, params=None):
""" Model definition """
if params.get("mixed_precision", True):
policy = Policy("infer_float32_vars") if mixed_precision else None
tf.keras.backend.floatx("float16")
logits = build_model(features, params)
learning_rate = tf.constant(params["lr"])
if mode in (tf.estimator.ModeKeys.TRAIN, tf.estimator.ModeKeys.EVAL):
loss_op = tf.cast(
tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
),
dtype=tf.float16 if params.get("mixed_precision", True) else tf.float32,
)
train_op = tf.train.GradientDescentOptimizer(
learning_rate=learning_rate
).minimize(loss_op, global_step=tf.train.get_global_step())
spec = tf.estimator.EstimatorSpec(mode=mode, loss=loss_op, train_op=train_op)
return spec