Tapering will emerge from an appropriate kernel smooth of a transformed streamflow grid. For a start, consider using the square root of stream flow and use an exponential kernel: the bandwidth of the kernel will determine the apparent width on the map.
Here is a sample workflow using operations commonly found in raster GISes such as Spatial Analyst, Idrisi, and--I believe--GRASS. It begins with a flow accumulation grid. A running example works with this one (a full 7.5 minute USGS DEM, 30 meter resolution, showing the log flow with graduated colors):
Limit the streams to points having a flow accumulation exceeding some threshold. (This is routine).
Compute distance and proximity grids to the stream cells. To do this you usually need to convert the streamflow itself to a categorical ("integer") grid. The proximity grid, by definition, contains the value of the nearest streamflow cell.
Here is the proximity grid shown on the same log scale as the first grid:
Compute the square root of the proximity. Divide the distance by the negative of the bandwidth and exponentiate the result. Multiply these two grids.
In this final image, steams (as after step 1, now shown in cyan) are overlaid on the result (shown in graduated shades of gray). The white-gray contour creates a visual threshold providing a good tapering effect. Vary the contour threshold to control the apparent width of the taper.